[英]Valgrind complaining about call to fgets
我有以下代碼:
int main(int argc, char const *argv[])
{
FILE *fp = NULL;
char *buffer = malloc(sizeof(char) * 150);
char roomElements[150];
char *roomSize = NULL;
int i = 1;
int *size = NULL; // does this need to be malloced?
char input = '\0';
check(argc == 2, "Please enter two arguments");
fp = openFile((char*)argv[1], "r");
initscr(); // ncurses
noecho();
/*Draws rooms and items*/
while (fgets(buffer, 150, fp)) { // line 25
removeNewLine(buffer);
strcpy(roomElements, strchr(buffer, ' '));
roomSize = strtok(buffer, " "); // get the room size
size = getRoomSize(roomSize, i); // convert room size to int pointer
drawRoom(size, i); // draw the room
tokenizeRoom(roomElements, i); // draw the elements
i++;
free(size);
}
/*This is the user input loop*/
do {
input = getch();
getInput(input);
} while (input != 'q');
free(buffer);
fclose(fp);
endwin();
return 0;
error:
return -1;
}
Valgrind輸出:
==74014== Memcheck, a memory error detector
==74014== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==74014== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info
==74014== Command: ./bin/rogue assets/room.txt
==74014==
==74014== Invalid read of size 32
==74014== at 0x10043EC1D: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==74014== by 0x10023080A: fgets (in /usr/lib/system/libsystem_c.dylib)
==74014== by 0x100000E10: main (main.c:25)
==74014== Address 0x100918a40 is 32 bytes before a block of size 4,096 in arena "client"
==74014== Conditional jump or move depends on uninitialised value(s)
==74014== at 0x10043EC7A: _platform_memchr$VARIANT$Haswell (in /usr/lib/system/libsystem_platform.dylib)
==74014== by 0x10023080A: fgets (in /usr/lib/system/libsystem_c.dylib)
==74014== by 0x100000E10: main (main.c:25)
==74014== Uninitialised value was created by a heap allocation
==74014== at 0x100008601: malloc (vg_replace_malloc.c:303)
==74014== by 0x100233836: __smakebuf (in /usr/lib/system/libsystem_c.dylib)
==74014== by 0x100236E99: __srefill0 (in /usr/lib/system/libsystem_c.dylib)
==74014== by 0x100236F94: __srefill (in /usr/lib/system/libsystem_c.dylib)
==74014== by 0x1002307DA: fgets (in /usr/lib/system/libsystem_c.dylib)
我可能做錯了什么? 一切都初始化了,我很茫然。 這個主題上沒有其他答案可以幫助我。 我不確定為什么它會抱怨fgets調用。
第2次編輯,我將顯示更多代碼。 這是openFile()
FILE *openFile(char *file, char *mode) {
FILE *fp = NULL;
fp = fopen(file, mode);
check(fp, "Could not open %s", file);
return fp;
}
這是getRoomSize
int *getRoomSize(char *size, int roomNum) { // rows x columns
int row, col;
char strRow[5], strCol[5];
int *roomSize = malloc(sizeof(int) * 2);
check(roomNum < 7 && roomNum > 0, "Invalid room to be drawn");
/*Convert string to int*/
strcpy(strRow, strtok(size, "X"));
strcpy(strCol, strtok(NULL, "X"));
row = atoi(strRow);
col = atoi(strCol);
roomSize[0] = row;
roomSize[1] = col;
return roomSize;
}
編輯3:這是我的MCVE。 它重現了條件跳轉和未初始化的值錯誤:
int main(int argc, char const *argv[])
{
char *buffer= malloc(sizeof(char) * 150);
char roomElements[300] = {0};
int i = 1;
FILE *fp = fopen(argv[1], "r");
if (!fp) {
printf("no\n");
exit(0);
}
while (fgets(buffer, 150, fp)) {
strcpy(roomElements, strchr(buffer, ' '));
i++;
}
free(buffer);
return 0;
}
該文件是包含此行的6次.txt
文件: 15X20 dn2 de10 dw11 g4,2 m10,17 M12,7 M4,9 p11,14 w10,10
我認為這可能是一個錯誤的警報。
fgets
內部使用memchr
來檢查是否已找到換行符。 你的平台memchr
是一種高度優化的匯編程序(這個名字表明它是專門為Haswell的架構進行了優化),這(可能使用一些SSE指令這樣做),在同一時間找到目標人物讀取32個字節。 在緩沖區的末尾, memchr
在您的150字節分配結束memchr
運行,並且valgrind抱怨。
這是完全安全的; memchr
堅持對齊的32字節邊界,則它不可能碰到壞內存,因為頁面分配大小為(至少)4096字節。 如果它在未初始化的內存中找到目標字符,則大概會檢測到所定位的字符超出了應搜索的字符串的結尾,並在這種情況下返回了正確的結果。
我會忽略此錯誤。 Valgrind偶爾會產生誤報。 考慮獲取或制作特定於平台的禁止文件,以自動忽略這些錯誤警報。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.