contributed by < allenchen8210
>
- 請補上實驗環境
- 中英文字間請以空白隔開
- git commit message 應具體提出哪些修改,而非指說明改了哪個 function,請修正
課程助教
Architecture: x86_64
Operating Sysetem: ubuntu16.04LTS
jn
2018.09.27進度總結
Consistent Code Style
>。code block 可以加上程式語言名稱,會有 syntax highlight,增加可讀性
課程助教
謝謝助教
jn
bool q_insert_head(queue_t *q, char *s)
{
if(s==NULL)
return false;
list_ele_t *newh;
/* What should you do if the q is NULL? */
if (malloc(sizeof(list_ele_t)) == NULL)
return false;
else
newh = malloc(sizeof(list_ele_t));
/* Don't forget to allocate space for the string and copy it */
/* What if either call to malloc returns NULL? */
newh->next = q->head;
char *list_value;
list_value = malloc(sizeof(*s));
*list_value = *s;
newh->value = list_value;
q->head = newh;
(q->qsize)++;
return true;
}
請直接複製文字內容,避免截圖
課程助教
最後發現是因為原來在在 Insert head 1.0 第15行 list_value = malloc(sizeof(*s)); 沒有正確取到 string 長度,應該是需要 list_value = malloc((strlen(s)+1); ,詳細可以看下面 Insert Head 2.0 第12行。
jn
bool q_insert_head(queue_t *q, char *s)
{
if (!q || !s)
return false;
list_ele_t *newh = malloc(sizeof(*newh));
if (!newh)
return false;
char *content = malloc(sizeof(strlen(s) + 1));
if (!content) {
free(newh);
return false;
}
strcpy(content, s);
if (!q->qsize) {
q->head = newh;
q->tail = newh;
newh->next = NULL;
newh->value = content;
} else {
newh->next = q->head;
newh->value = content;
q->head = newh;
}
q->qsize++;
return true;
}
#include <stdlib.h>
#include <string.h>
typedef struct rec {
char *value;
struct rec *next;
} record;
void insert_sorted(record **r, const char *value)
{
record *newrec = NULL;
while (*r && strcmp(value, (*r)->value) > 0)
r = &((F1)->next);
newrec = malloc(sizeof(record));
newrec->value = F2(value);
newrec->next = F3;
F4 = newrec;
}
這邊 F2 答案是 strcpy ,有個問題是 strcpy 不是需要兩個參數? 查詢 Linux Programmer's Manual 如右 http://man7.org/linux/man-pages/man3/strcpy.3.html
int main () {
char *src = "hello world";
char *dest = (char*)(malloc((sizeof(strlen(src)+1))));
if(!dest)
return 0;
dest = strcpy(src);
printf("Final copied string : %s\n", dest);
return(0);
}
test.c: In function ‘main’:
test.c:11:11: error: too few arguments to function ‘strcpy’
dest = strcpy(src);
考慮以下程式碼,在 little-endian 硬體上,會返回 1
,反之,在 big-endian 硬體上會返回 0
:
int main() {
union { int a; char b;
} c = { .a = K1 };
return c.b == K2;
}
這邊有個問題是,當union 在配置記憶體時,配置的空間是可以容納最大的 data type ,但是如題目,這樣 char 怎麼知道配置到什麼位置記憶體?上面的假設是當 overlapping 都取最低位置
little-endian & big-endian
How do I print bits in C?
+++ TESTING trace trace-07-robust:
# Test operations on NULL queue
--- trace-07-robust 7/7
+++ TESTING trace trace-08-robust:
# Test operations on empty queue
--- trace-08-robust 7/7
+++ TESTING trace trace-09-robust:
# Test remove_head with NULL argument
--- trace-09-robust 7/7
+++ TESTING trace trace-10-malloc:
# Test of malloc failure on new
--- trace-10-malloc 7/7
+++ TESTING trace trace-11-malloc:
# Test of malloc failure on insert_head
--- trace-11-malloc 7/7
+++ TESTING trace trace-12-malloc:
# Test of malloc failure on insert_tail
--- trace-12-malloc 7/7
+++ TESTING trace trace-13-perf:
# Test performance of insert_tail
--- trace-13-perf 7/7
+++ TESTING trace trace-14-perf:
# Test performance of size
--- trace-14-perf 7/7
+++ TESTING trace trace-15-perf:
# Test performance of insert_tail, size, and reverse
--- trace-15-perf 7/7
--- TOTAL 87/100
在碰到 coed 格式不符合時,其實一開始只知道自己的 code 沒有符合規範,看完同學的流程才知道必須下第一行(1.) command 才過得了。
但我自己實際做完後下去比較跟我原本沒修改的長得一樣,不清楚差別在那,還是只要有修改過一定要下第一行(1.) command?
更新心得
常常會出錯都在 free(), malloc() , 這兩個很容易出錯,我假設其中一個 malloc() 有分到記憶體,另一個 malloc() 沒分到,測試程式也會抓得到,什麼時候自己有配置記憶體時一定要清楚,不然沒 free() ,就可能會產生 memory leak 問題,學 C 的好處就是充分掌握硬體。
+++ TESTING trace trace-03-ops:
# Test of insert_head, insert_tail, reverse, and remove_head
ERROR: Corruption detected in block with address 0x848d20 when attempting to free it
--- trace-03-ops 0/6
+++ TESTING trace trace-04-ops:
# Test of insert_head, insert_tail, and size
--- trace-04-ops 6/6
+++ TESTING trace trace-05-ops:
# Test of insert_head, insert_tail, remove_head reverse, and size
--- trace-05-ops 6/6
+++ TESTING trace trace-06-string:
# Test of truncated strings
在使用 ih it 使用很長的字串,常常會有錯誤,如下,目前乃然無法解決,假設單個字元,不會有這樣問題,讓我有點傷腦筋,停在87分,如果沒辦法解決,明天就會跳過往 qtest 先做。
p.s. 發現超過 queue 在 free 8個字元就會出問題,就算 queue 只有一個8個字元,在free時也會出問題,然而 queue 有20000個7個字元在 free 時也不會出問題。
cmd>new
cmd>new
q = []
cmd>ih 1234567 20000
cmd>ih 1234567 20000
q = [1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 1234567 ... ]
cmd>free
cmd>free
q = NULL
cmd>new
cmd>new
q = []
cmd>ih 12345678
cmd>ih 12345678
q = [12345678]
cmd>free
cmd>free
ERROR: Corruption detected in block with address 0x12779b0 when attempting to free it
q = NULL
cmd>
+++ TESTING trace trace-13-perf:
# Test performance of insert_tail
--- trace-13-perf 7/7
+++ TESTING trace trace-14-perf:
# Test performance of size
--- trace-14-perf 7/7
+++ TESTING trace trace-15-perf:
# Test performance of insert_tail, size, and reverse
--- trace-15-perf 7/7
--- TOTAL 100/100
bool q_insert_head(queue_t *q, char *s)
{
if (!q || !s)
return false;
list_ele_t *newh = malloc(sizeof(*newh));
if (!newh)
return false;
char *content = malloc(sizeof(strlen(s) + 1));
if (!content) {
free(newh);
return false;
}
strcpy(content, s);
if (!q->qsize) {
q->head = newh;
q->tail = newh;
newh->next = NULL;
newh->value = content;
} else {
newh->next = q->head;
newh->value = content;
q->head = newh;
}
q->qsize++;
return true;
}
bool q_insert_head(queue_t *q, char *s)
{
if (!q || !s)
return false;
list_ele_t *newh = malloc(sizeof(*newh));
if (!newh)
return false;
int s_len = strlen(s)+1;
//printf("string length excluding the terminating null byte = %d bytes\n", s_len-1);
char *content = (char*)malloc(s_len*sizeof(char));
if (!content) {
free(newh);
return false;
}
//printf("obtain %lu bytes from malloc\n", strlen(content));
strcpy(content, s);
//printf("actually obtain %lu bytes after use strcpy\n", strlen(content));
if (!q->qsize) {
q->head = newh;
q->tail = newh;
newh->next = NULL;
newh->value = content;
} else {
newh->next = q->head;
newh->value = content;
q->head = newh;
}
q->qsize++;
return true;
}
allen@Mac:~/lab0-c$ ./qtest
cmd>new
cmd>new
q = []
cmd>ih 1234567890
cmd>ih 1234567890
string length excluding the terminating null byte = 10 bytes
obtain 15 bytes from malloc
actually obtain 10 bytes after use strcpy
q = [1234567890]
cmd>quit
cmd>quit
Freeing queue
今天早上才在想,要做甚麼東西?目的是甚麼?我本身很在意空氣品質,我來台南已經快四年了,可以很明顯感受到空氣品質的下降。科技的發展,也犧牲了台灣人民的健康,看似微乎其微,但深深影響了我們。會不會有那麼一天大家出去除了得看今天會不會下雨?還要看今天空氣好不好?天氣我們不能掌控,但空氣的品質是我們大家可以監督的,雖然目前政府不承認這種民間的空氣盒子,但我想我們還有很多努力的空間,這是是一個貧富差距不斷跨大的年代,但也因為網路而拉進你我的距離。我想我找到著力點了。
這邊有個 FB粉專 也是會討論關於中南部空氣品質,希望大家讓這個議題不斷擴大。
CC = gcc
CFLAGS = -O0 -g -Wall -Werror
GIT_HOOKS := .git/hooks/applied
all: $(GIT_HOOKS) qtest
$(GIT_HOOKS):
@scripts/install-git-hooks
@echo
queue.o: queue.c queue.h harness.h
$(CC) $(CFLAGS) -c queue.c
qtest: qtest.c report.c console.c harness.c queue.o
$(CC) $(CFLAGS) -o qtest qtest.c report.c console.c harness.c queue.o
test: qtest scripts/driver.py
scripts/driver.py
clean:
rm -f *.o *~ qtest
rm -rf *.dSYM
driver.py 裡面這個不了解,不清楚第一行的 name 哪裡來的? 還需要再了解
if __name__ == "__main__":
run(sys.argv[0], sys.argv[1:])
自使用自動評分系統時,主要還是透過 driver.py 去執行 ./qtest,蠻有趣的。第9行 retcode = subprocess.call(clist), 可以用讓 python 來執行外部程式。
def runTrace(self, tid):
if not tid in self.traceDict:
print "ERROR: No trace with id %d" % tid
return False
fname = "%s/%s.cmd" % (self.traceDirectory, self.traceDict[tid])
vname = "%d" % self.verbLevel
clist = [self.qtest, "-v", vname, "-f", fname]
try:
retcode = subprocess.call(clist)
except Exception as e:
print "Call of '%s' failed: %s" % (" ".join(clist), e)
return False
return retcode == 0
接著就是解析指令,透過 getopt() 來解,舉下面 "hv:f:l:" 這個例子,會去找 有沒有 h hv v f l ,後面有冒號就是必須要有另外一個參數,然後傳給 optarg。
while ((c = getopt(argc, argv, "hv:f:l:")) != -1) {
switch (c) {
case 'h':
usage(argv[0]);
break;
case 'f':
strncpy(buf, optarg, BUFSIZE);
buf[BUFSIZE - 1] = '\0';
infile_name = buf;
break;
case 'v':
level = atoi(optarg);
break;
case 'l':
strncpy(lbuf, optarg, BUFSIZE);
buf[BUFSIZE - 1] = '\0';
logfile_name = lbuf;
break;
default:
printf("Unknown option '%c'\n", c);
usage(argv[0]);
break;
}
}
解析完指令,不知道怎麼丟進去 20181004
jn