2016-08-18 19 views
-1

我完成了所有的功能,但是我的代碼沒有通過第二次檢查。我不確定問題出在哪裏,但可能是在我的加載或索引函數中,因爲我的代碼成功通過了第一次檢查。有人可以幫我弄清楚嗎?噢,出於某種原因,我的GDB不工作。提前致謝!cs50 pset6加載或索引函數出錯

這裏是我的代碼:

char *indexes(const char *path) { 
    char *copy = malloc(strlen(path)); 
    strcpy(copy, path); 

    char *php = "/index.php\0"; 
    char *html = "/index.html\0"; 

    char *check_php = malloc(strlen(copy) + strlen(php)); 
    char *check_html = malloc(strlen(copy) + strlen(html)); 

    check_php = strcat(copy, php); 
    check_html = strcat(copy, html); 

    if (access(check_php, F_OK) == 0) 
     return check_php; 
    else 
    if (access(check_html, F_OK) == 0) 
     return check_html; 

    return NULL; 
} 

bool load(FILE *file, BYTE **content, size_t *length) { 
    char *store = malloc(5000); 
    int count = 0; 
    char c; 

    do { 
     c = fgetc(file); 

     if (feof(file)) 
      break; 
     else 
     if (count % 5000 == 0) 
      store = realloc(store, count + 5000); 

     store[count] = c; 
     count++; 
    } while (true); 

    *content = &store[0]; 
    *length = count; 

    return true; 
} 

回答

1

我道歉,如果這是不是這樣,但你不應該分配更多的內存拷貝?通過strcat的定義(char * strcat(char * dest,const char * src)) 參數 dest - 這是指向目標數組的指針,它應該包含一個C字符串,並且應該足夠大以包含串聯結果字符串。但是你只分配了拷貝只有strlen的路徑。

3

有在你的代碼中的許多問題:

  • 有一個在功能indexes()一個經典的錯誤:

    char *copy = malloc(strlen(path)); 
    strcpy(copy, path); 
    

    必須爲空終止分配多一個字節:

    char *copy = malloc(strlen(path) + 1); 
    strcpy(copy, path); 
    

    或者你可以使用posix功能strdup() if ava ilable您的系統上:

    char *copy = strdup(path); 
    
  • 爲您拼接嘗試類似的問題:

    char *check_php = malloc(strlen(copy) + strlen(php)); 
    char *check_html = malloc(strlen(copy) + strlen(html)); 
    
    check_php = strcat(copy, php); 
    check_html = strcat(copy, html); 
    

    你沒有分配足夠的內存,你不字符串複製到分配的內存中,而不是你連接到已經滿的copy的末尾。而應該寫:

    char *check_php = malloc(strlen(copy) + strlen(php) + 1); 
    char *check_html = malloc(strlen(copy) + strlen(html) + 1); 
    
    strcpy(check_php, copy); 
    strcpy(check_php, php); 
    
    strcpy(check_html, copy); 
    strcpy(check_html, html); 
    
  • 你不free你離開這個功能之前,不再使用字符串。這是馬虎,導致內存泄漏。

有在功能上load()更多的問題,並不重要的:

  • fgetc()的返回值應該被存儲到一個int。您檢查文件的末尾,而不是技術上的錯誤,很容易出錯,不推薦的方式,則應該這樣寫:

    int c = fgetc(fp); 
    if (c == EOF) 
        break; 
    
  • 的重分配方案是多餘的:如果count == 0調用realloc()具有相同的大小作爲您的初始malloc()呼叫。您可以將store初始化爲NULL並僅依靠realloc進行分配。如果文件爲空,則*length將設置爲0*bytesNULL,這應該是確定的。

    另一種方法是在將指針存儲到*bytes之前將store重新分配爲實際讀取的大小。

  • do { ... } while (true);不是讀者友好的:使用for (;;) { ... }來立即告訴讀者這個無限循環的本質會好得多。

2

代碼中有很多錯誤。我創建了兩個版本。一個與錯誤註釋和糾正。另一個清理和簡化。

這裏是註釋版本#if 0 /*original code*/ #else /*fixed code*/ #endif

char * 
indexes(const char *path) 
{ 
    // NOTE/BUG: malloc for string must allow for EOS char 
#if 0 
    char *copy = malloc(strlen(path)); 
#else 
    char *copy = malloc(strlen(path) + 1); 
#endif 

    // NOTE/BUG: no need to duplicate path -- it can be used directly 
    strcpy(copy, path); 

    // NOTE/BUG: the \0 is redundant 
#if 0 
    char *php = "/index.php\0"; 
    char *html = "/index.html\0"; 
#else 
    char *php = "/index.php"; 
    char *html = "/index.html"; 
#endif 

    // NOTE/BUG: malloc for string must allow for EOS char 
#if 0 
    char *check_php = malloc(strlen(copy) + strlen(php)); 
    char *check_html = malloc(strlen(copy) + strlen(html)); 
#else 
    char *check_php = malloc(strlen(copy) + strlen(php) + 1); 
    char *check_html = malloc(strlen(copy) + strlen(html) + 1); 
#endif 

    // NOTE/BUG: copy doesn't have enough space to hold the concat and is wrong 
    // NOTE/BUG: this is trashing the above values and, thus, leaking memory 
#if 0 
    check_php = strcat(copy, php); 
    check_html = strcat(copy, html); 
#else 
    strcpy(check_php,copy); 
    strcat(check_php,php); 
    strcpy(check_html,copy); 
    strcat(check_html,html); 
#endif 

    // NOTE/BUG: this is leaking memory of the unused check_html 
#if 0 
    if (access(check_php, F_OK) == 0) 
     return check_php; 
#else 
    if (access(check_php, F_OK) == 0) { 
     free(check_html); 
     return check_php; 
    } 
#endif 

    // NOTE/BUG: this is leaking memory of the unused check_php 
#if 0 
    if (access(check_html, F_OK) == 0) 
     return check_html; 
#else 
    if (access(check_html, F_OK) == 0) { 
     free(check_php); 
     return check_html; 
    } 
#endif 

    // NOTE/BUG: this is leaking memory of the unused check_php and check_html 
#if 1 
    free(check_html); 
    free(check_php); 
#endif 
    return NULL; 
} 

這裏是清理版本:

char * 
indexes(const char *path) 
{ 
    char *php = "/index.php"; 
    char *html = "/index.html"; 
    size_t plen = strlen(path); 
    char *file; 

    file = malloc(plen + strlen(php) + 1); 
    strcpy(file,path); 
    strcat(file,php); 
    if (access(file, F_OK) == 0) 
     return file; 
    free(file); 

    file = malloc(plen + strlen(html) + 1); 
    strcpy(file,path); 
    strcat(file,html); 
    if (access(file, F_OK) == 0) 
     return file; 
    free(file); 

    return NULL; 
}