Valgrind 对写入的未初始化值大喊大叫

发布于 2024-11-14 09:33:45 字数 3853 浏览 1 评论 0原文

该函数用从文件读取的数据填充动态生成的数组。 Valgrind 喊道:

==21124== Syscall param write(buf) points to uninitialised byte(s)
==21124==    at 0x410D013: write (in /lib/libc-2.13.so)
==21124==    by 0x8049839: main (mmboxd.c:437)
==21124==  Address 0x41b49e6 is 6 bytes inside a block of size 344 alloc'd
==21124==    at 0x4026D0E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21124==    by 0x8049924: messagesList (mmboxd.c:468)
==21124==    by 0x80497F1: main (mmboxd.c:432)
==21124== 

我猜 write 函数是由 realloc 调用的,但是 realloc 正在写入的结构体已填充在每个字段中。怎么了?
这里是函数、scruct 和调用它的主段:

typedef struct 
{
char sender[41], recipient[41];   /* mittente e destinatario */
char obj[41], date[41];           /* oggetto e data del messaggio */
char flags;                       /* letto o no,marcato o no per la cancellazione */
size_t size;                      /* dimensione in bytes del corpo del messaggio */
} mmbox_mail_complete;

mmbox_mail_complete *messagesList(char *username, int *nmails)
{
/* NB - MAILBOX è così composta: 6 righe per ogni messaggio -->  1 mittente, 2 oggetto, 3 data, 4 flags, 5 size, 6 messaggio */
mmbox_mail_complete *mails = NULL;   /* array di mail */
int n = 0;                           /* dimensione dell'array di mail */
int input;                           /* carattere letto */
char line[40];                       /* linea letta */
int k;                               /* contatore */
FILE *file;                          /* puntatore al file da leggere/scrivere */    

/* apro il file dell'utente */
if(!(file = fopen(userPath(username), "r")))   logMmboxd("failed opening user mailbox\n", 1);
else                                           logMmboxd("succeded in opening user mailbox\n", 0);

/* leggo una riga alla volta appunto a partire dalla seconda e la stipo */
while((input = fgetc(file)) != EOF)   
{  
    /* riavvolgo di un carattere avanzato nel caso non fosse EOF nella condizione del ciclo */
    if(fseek(file, -1, SEEK_CUR) == -1)   logMmboxd("failed seeking mailbox\n", 1);
    else                                  logMmboxd("seeked mailbox\n", 0);

    /* alloco una nuova mail */
    mails = realloc(mails, sizeof(mmbox_mail_complete) * (n+1));
    n++;

    /* leggo il mittente */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   mails[n-1].sender[k] = input; 
    mails[n-1].sender[k] = '\0';    

    /* leggo il mittente (in realtà ce l'ho gia in username) */
    for(k=0; username[k] != '\0'; k++)   mails[n-1].recipient[k] = username[k]; 
    mails[n-1].recipient[k] = '\0'; 

    /* leggo l'oggetto */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   mails[n-1].obj[k] = input; 
    mails[n-1].obj[k] = '\0';   

    /* leggo la data */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   mails[n-1].date[k] = input; 
    mails[n-1].date[k] = '\0';

    /* leggo il flag */
    input = fgetc(file);
    mails[n-1].flags = input;
    input = fgetc(file);

    /* leggo la dimensione del messaggio */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   line[k] = input; 
    line[k] = '\0';
    mails[n-1].size = atoi(line);   

    /* mando avanti il puntatore nel file della lunghezza del messaggio */
    if(fseek(file, mails[n-1].size+1, SEEK_CUR) == -1)   logMmboxd("failed seeking (size) mailbox\n", 1);
    else                                                 logMmboxd("seeked mailbox\n", 0);
}
*nmails = n;

fclose(file);
return mails;
}


 /* in the main: the response struct is already memset to 0 */
response.result = SUCCESS;
mails = messagesList(users[k].username, &response.num);
response.num2 = 0;
response.size = sizeof(mmbox_mail_complete) * response.num;
answer(&response, mails);           /* 437 line */              

this function fills an array dinamically generated with data read from a file. Valgrind yells this:

==21124== Syscall param write(buf) points to uninitialised byte(s)
==21124==    at 0x410D013: write (in /lib/libc-2.13.so)
==21124==    by 0x8049839: main (mmboxd.c:437)
==21124==  Address 0x41b49e6 is 6 bytes inside a block of size 344 alloc'd
==21124==    at 0x4026D0E: realloc (in /usr/lib/valgrind/vgpreload_memcheck-x86-linux.so)
==21124==    by 0x8049924: messagesList (mmboxd.c:468)
==21124==    by 0x80497F1: main (mmboxd.c:432)
==21124== 

The write function is called by realloc I guess,but the struct realloc is writing is filled in every field. What's wrong?
Here the function, the scruct and the main segment where it is called:

typedef struct 
{
char sender[41], recipient[41];   /* mittente e destinatario */
char obj[41], date[41];           /* oggetto e data del messaggio */
char flags;                       /* letto o no,marcato o no per la cancellazione */
size_t size;                      /* dimensione in bytes del corpo del messaggio */
} mmbox_mail_complete;

mmbox_mail_complete *messagesList(char *username, int *nmails)
{
/* NB - MAILBOX è così composta: 6 righe per ogni messaggio -->  1 mittente, 2 oggetto, 3 data, 4 flags, 5 size, 6 messaggio */
mmbox_mail_complete *mails = NULL;   /* array di mail */
int n = 0;                           /* dimensione dell'array di mail */
int input;                           /* carattere letto */
char line[40];                       /* linea letta */
int k;                               /* contatore */
FILE *file;                          /* puntatore al file da leggere/scrivere */    

/* apro il file dell'utente */
if(!(file = fopen(userPath(username), "r")))   logMmboxd("failed opening user mailbox\n", 1);
else                                           logMmboxd("succeded in opening user mailbox\n", 0);

/* leggo una riga alla volta appunto a partire dalla seconda e la stipo */
while((input = fgetc(file)) != EOF)   
{  
    /* riavvolgo di un carattere avanzato nel caso non fosse EOF nella condizione del ciclo */
    if(fseek(file, -1, SEEK_CUR) == -1)   logMmboxd("failed seeking mailbox\n", 1);
    else                                  logMmboxd("seeked mailbox\n", 0);

    /* alloco una nuova mail */
    mails = realloc(mails, sizeof(mmbox_mail_complete) * (n+1));
    n++;

    /* leggo il mittente */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   mails[n-1].sender[k] = input; 
    mails[n-1].sender[k] = '\0';    

    /* leggo il mittente (in realtà ce l'ho gia in username) */
    for(k=0; username[k] != '\0'; k++)   mails[n-1].recipient[k] = username[k]; 
    mails[n-1].recipient[k] = '\0'; 

    /* leggo l'oggetto */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   mails[n-1].obj[k] = input; 
    mails[n-1].obj[k] = '\0';   

    /* leggo la data */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   mails[n-1].date[k] = input; 
    mails[n-1].date[k] = '\0';

    /* leggo il flag */
    input = fgetc(file);
    mails[n-1].flags = input;
    input = fgetc(file);

    /* leggo la dimensione del messaggio */
    for(k=0; (input=fgetc(file)) != '\n' && input != EOF; k++)   line[k] = input; 
    line[k] = '\0';
    mails[n-1].size = atoi(line);   

    /* mando avanti il puntatore nel file della lunghezza del messaggio */
    if(fseek(file, mails[n-1].size+1, SEEK_CUR) == -1)   logMmboxd("failed seeking (size) mailbox\n", 1);
    else                                                 logMmboxd("seeked mailbox\n", 0);
}
*nmails = n;

fclose(file);
return mails;
}


 /* in the main: the response struct is already memset to 0 */
response.result = SUCCESS;
mails = messagesList(users[k].username, &response.num);
response.num2 = 0;
response.size = sizeof(mmbox_mail_complete) * response.num;
answer(&response, mails);           /* 437 line */              

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

傾城如夢未必闌珊 2024-11-21 09:33:45

您不会写入发送者/接收者名称的整个字段,而只会写入第一个 NUL 字节。虽然如果 NUL 终止符后面的字节未初始化,您的程序可能会正确运行,但 valgrind 无法知道这是一个字符串并且这些字节是不相关的。

You are not writing the entire field for the sender/recipient names, but only until the first NUL byte. While your program is probably going to operate correctly if the bytes following the NUL terminator are not initialized, valgrind cannot know that this is a string and that these bytes are irrelevant.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文