此函数用从文件读取的数据填充一个dinamically生成的数组。 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==
我想,realloc会调用write函数,但是每个字段都会填充struct 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 */
答案 0 :(得分:1)
您不是为发件人/收件人名称编写整个字段,而是直到第一个NUL字节。如果NUL终结符后面的字节没有被初始化,你的程序可能会正常运行,而valgrind不能知道这是一个字符串,而且这些字节是无关紧要的。