簡體   English   中英

Valgrind抱怨調用fgets

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM