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

标签 c valgrind

此函数用从文件中读取的数据填充动态生成的数组。 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 调用的,但是正在写入的 struct realloc 被填充在每个字段中。怎么了?
这里是函数、结构体和调用它的主要部分:

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 */              

最佳答案

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

关于c - Valgrind 对写入的未初始化值大喊大叫,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6264727/

相关文章:

c++ - 如何让 Valgrind 不检测特定的共享对象?

c++ - OSX Yosemite 上的 Valgrind callgrind

c++ - 如果我打开文件后有人覆盖该文件会怎样?

c - setgid 不适用于/tmp/

c - Bazel:使用宏从列表生成构建规则

c - 使用 valgrind 和 gdb 进行调试

c - 如何正确关闭和释放ALSA资源

c - 将字符串转换为代码?

c - 将 typedef 从 header 传递到源 - C

c - 打开文件会导致 sYSMALLOc 断言失败