2015-02-11 60 views
2

實際上還要考慮我有這兩個錯誤,可能需要一些幫助尋找了很長時間後,找到一個解決方案: Valgrind的錯誤,大小和條件跳轉或移動的無效讀取上未初始化值

==4902== 1 errors in context 1 of 2: 
==4902== Invalid read of size 1 
==4902== at 0x4010A0: getData (main.c:321) 
==4902== by 0x402527: main (main.c:783) 
==4902== Address 0x52007af is 1 bytes before a block of size 2,152 alloc'd 
==4902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==4902== by 0x400FF1: getData (main.c:309) 
==4902== by 0x402527: main (main.c:783) 
==4902== 
==4902== 
==4902== 1 errors in context 2 of 2: 
==4902== Conditional jump or move depends on uninitialised value(s) 
==4902== at 0x4C2E0E9: strlen (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==4902== by 0x40107A: getData (main.c:319) 
==4902== by 0x402527: main (main.c:783) 
==4902== Uninitialised value was created by a heap allocation 
==4902== at 0x4C2AB80: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) 
==4902== by 0x400FF1: getData (main.c:309) 
==4902== by 0x402527: main (main.c:783) 
char** buffer = malloc(file_size * sizeof(char**)); 
    if(buffer == NULL) 
    { 
    status = EXITCODE_4; 
    return status; 
    } 

    int buffer_counter = 0; 
    int buffer_length = 0; 

while(!feof(datafile)) 
    { 
    buffer[buffer_counter] = malloc(file_size * sizeof(char*)); 
    if(buffer[buffer_counter] == NULL) 
    { 
     status = EXITCODE_4; 
     free2D(buffer, buffer_counter); 
     return status; 
    } 

    fgets(buffer[buffer_counter], file_size, datafile); 

    buffer_length = strlen(buffer[buffer_counter]) - 1; 

    if((buffer[buffer_counter][buffer_length]) == NEWLINE) 
     buffer[buffer_counter][buffer_length] = 0; 
    buffer_counter++; 
    } 

線309是第二malloc的發生, 321如果 和319 strlen的

我不是很有經驗的Valgrind的,所以我不不知道如何解決這個問題。 Thx尋求任何幫助。

+1

一個修復建議'而(!FEOF(數據文件))'[永遠是錯的(http://stackoverflow.com/questions/5431941/while-feof-文件是 - 總是錯的)。 – 2015-02-11 01:35:05

+0

這一行:''buffer [buffer_counter] = malloc(file_size * sizeof(char *));應該是:'buffer [buffer_counter] = malloc(file_size);'因爲想要一個字符數組,而不是char – user3629249 2015-02-11 02:15:50

+0

的指針數組,應該清除初始malloc'd數組以使其全部爲NULL,以使其在釋放所有內存分配時相對容易。 – user3629249 2015-02-11 02:17:58

回答

1

變化

while (!feof(datafile)) 

while (fgets(buffer[buffer_counter], file_size, datafile) != NULL) 

因爲while (!feof(datafile))會遍歷一旦超出文件的末尾,讀why while (!feof(datafile)) is always wrong

EOF標記後fgets()嘗試讀取過去的文件的末尾設置,所以它需要一個額外的迭代要做到這一點,但fgets()將在文件的最後返回NULL,所以你會訪問未初始化的安全如果您在while循環條件中測試它的值。

當然,你將需要重新思考程序流程,我的建議是

char** buffer = malloc(file_size * sizeof(char *)); 
if (buffer == NULL) 
{ 
    status = EXITCODE_4; 
    return status; 
} 

int buffer_counter = 0; 
int buffer_length = 0; 
char line[file_size]; 

while (fgets(line, file_size, datafile) != NULL) 
{ 
    size_t length; 

    length = strlen(line); 
    if (line[length - 1] == NEWLINE) 
     line[--length] = '\0'; 
    buffer[buffer_counter] = malloc(1 + length); 
    if (buffer[buffer_counter] == NULL) 
    { 
     status = EXITCODE_4; 
     free2D(buffer, buffer_counter); 
     return status; 
    } 
    strcpy(buffer[buffer_counter], line); 
    buffer_counter++; 
} 

malloc(file_size * sizeof(char *))被分配更多的內存比你需要,你需要malloc(file_size * sizeof(char))sizeof(char) == 1所以只是malloc(file_size),我固定也無妨爲適合的確切字符串分配空間。

+0

哇謝謝你的回答!它現在有效。 – PinkieClownie 2015-02-11 01:44:08

+0

@PinkieClownie順便說一下,我很高興看到你檢查'malloc()'的返回值。保持這種風格,你會很開心,相信我。 – 2015-02-11 01:51:11

0

這裏是問題

char** buffer = malloc(file_size * sizeof(char**)); 
if(buffer == NULL) 
{ 
    status = EXITCODE_4; 
    return status; 
} 

// implied else, malloc successful 

// clear list of pointer to NULLs 
memset(buffer, 0x00, (file_size* sizeof(char**))); 

int buffer_counter = 0; 
int buffer_length = 0; 

while(0 < (buffer_length = getline(buffer[buffer_counter], file_size, datafile))) 
{ 

    if (0 >= buffer_length) 
    { 
     status = EXITCODE_4; 
     free2D(buffer, buffer_counter); 
     return status; 
    } 

    // implied else, getline successful 

    if((buffer[buffer_counter][buffer_length-1]) == NEWLINE) 
    { 
     // trim newline 
     buffer[buffer_counter][buffer_length-1] = '\0'; 
     buffer_length--; 
    } 

    buffer_counter++; 
} // end while 
相關問題