2012-02-09 65 views
1

我跑Valgrind的,我收到以下错误.. 之前我做了一个备份我固定的,但现在我不记得如何。物通过的malloc产生错误,但在代码Unitialised值(S)的valgrind

>Insert password for admin: ==5720== Conditional jump or move depends on uninitialised value(s) 
==5720== at 0x40299EB: strcmp (mc_replace_strmem.c:538) 
==5720== by 0x80496C6: adm_log_request (commands_man.c:169) 
==5720== by 0x80521CA: main (mmboxman.c:9) 
==5720== Uninitialised value was created by a heap allocation 
==5720== at 0x4028876: malloc (vg_replace_malloc.c:236) 
==5720== by 0x8049683: adm_log_request (commands_man.c:165) 
==5720== by 0x80521CA: main (mmboxman.c:9) 
==5720== 

这是函数 线commands_man我无法找到该错误:165是,如果后(大小> 0)

int adm_log_request(void){ 

FILE *password; 
char *pwdin, *frompwd = NULL; 
int primo = 0/*indica se è un primo avvio*/, tentativi = 2, p, size; 

if(!(password = fopen(F_PWD_ADM, "rb"))){ 
    primo = 1; 
    printf("First server boot\n>Insert password for admin: "); 
} 
else{ 
    primo = 0; 
    printf(">Insert password for admin: "); 
} 
p = get_hid_pass(&pwdin); 
if(p < 0) 
    return -1; 
switch(primo){ 
    case 0: 
     if(!(password = fopen(F_PWD_ADM, "r"))) 
      return -1; 
     fread(&size, sizeof(int), 1, password); 
     if(size > 0){ 
      frompwd = (char*)malloc(size + 1); 
      fread(frompwd,sizeof(frompwd),1,password); 
     }else return 0; 
     while(tentativi > 0){ 
      if(strcmp(pwdin, frompwd) != 0){ 
       printf("\nIncorrect password\n%d attempts left\n>Insert password for admin: ", tentativi); 
       tentativi--; 
      } 
      else return 1; 
      p = get_hid_pass(&pwdin); 
      if(p < 0) 
       return -1; 
     } 
     fclose(password); 
     break; 
    case 1:  //primo avvio del server 
     if(!(password = fopen(F_PWD_ADM, "w"))) 
      return -1; 
     size = strlen(pwdin) + 1; 
     fwrite(&size, sizeof(int), 1, password); 
     fwrite(pwdin, sizeof(pwdin), 1, password); 
     fclose(password); 
     break; 
} 
if(tentativi == 0) 
    return -1; 

return 1; 
} 

莫非有人帮我解决他们?谢谢你的问题

回答

1

部分看起来像sizeof一个问题:

 fread(frompwd,sizeof(frompwd),1,password); 

在上面的线,将的sizeof有4个(假设32位体系结构)的值。这可能是因为你需要通过size的长度。然后它仍然需要在此之后被终止。

frompwd[size] = '\0'; 

fwrite通话也有类似的问题,将只写4个字节的密码。

+0

我发现问题..它在 size = strlen(pwdin)+ 1; +1错了!谢谢!! =) – roccocullo 2012-02-09 15:46:53

+0

@roccocullo:这取决于你是否想写空终止符字节或不。并且请注意,'fwrite'调用仍然需要被赋予正确的长度(大小)而不是sizeof结果。 – 2012-02-09 15:49:15

0

也许fread实际上并没有设置size什么吗?

它不会保证它会。见(从the man page)其返回值:

返回值

的功能的fread()和fwrite()由数字超前的文件位置指示器 用于流的字节读出或写入。他们返回读取或写入的对象数量。如果发生错误或达到文件结尾,则返回值为短对象计数(或零)。

函数的fread()之间没有区分结束文件和错误;呼叫者必须使用feof(3)和ferror(3)来确定发生了哪一个。只有在发生写入错误 时,函数fwrite()才会返回一个小于nitems的值。

如果返回值是例如0,则size仍然未初始化管线165。一个好的做法是检查fread返回的内容并确认实际读取的值是否成功。

0

首先,从文件中读取4个字节(或8个64位):

fread(frompwd,sizeof(frompwd),1,password); 

你可能并不意味着在这里使用sizeof(frompwd)

然后你,比较使用STRCMP:

strcmp(pwdin, frompwd) 

strcmp进行比较,直到两个字符串一个包含NUL '\ 0' 字符。在这种情况下,你从来没有终止你的密码字符串,因此消息。

您应该a)使用正确的读取大小,并b)使用strncmp以确保您没有像这样的缓冲区溢出错误。

+0

实际上错误来自pwd [size] ='\ 0'; :) – roccocullo 2012-02-09 16:03:44

+0

不要忘记为终结者分配空间。你需要字符串大小加1。 – ams 2012-02-10 09:25:13