此函数用从文件中读取的数据填充动态生成的数组。 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/