2013-08-03 60 views
0

我有以下的C文件命名爲main.c中:Valgrind的:條件跳轉或移動依賴於未初始化值

#include <stdio.h> 
#include <string.h> 

#define NUM_CHAR 20 

int main(void) { 
    char command_line[NUM_CHAR + 2]; /* Command line string includes the new line character ('\n') and a null character ('\0') */ 
    while (1) { 
     if (fgets(command_line, sizeof(command_line), stdin) == NULL) { /*This function reads up to sizeof(command_line)-1 characters, or until it encounters the new line character. The function adds '\0' to the end of the array */ 
      perror("Error: standard function fgets has failed"); 
      break; 
     } 

     if (command_line[sizeof(command_line) - 2] != '\n' && strlen(
       command_line) == NUM_CHAR + 1) { /*# of characters (excluding '\n') in command_line is <=num_char iff the condition takes place. */ 
      printf(
        "Error: command length must be less than or equal  to %d characters\n", 
       NUM_CHAR); 
     while (getchar() != '\n') { 
     } /* read the remaining characters */ 
     continue;/* continue with while(1) loop */ 
     } 

     printf("%s",command_line); 

     if (command_line[0] == 'Q') { 
      break; 
     } 
    } 
    return 0; 
} 

下面的行了一個名爲輸入文本文件:

Quit 

這是我在終端上運行的valgrind後得到了(節目的名稱也是主):

[email protected]:~/workspace/tests$ valgrind --track-origins=yes --leak-check=full ./main < input 
==2649== Memcheck, a memory error detector 
==2649== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. 
==2649== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info 
==2649== Command: ./main 
==2649== 
==2649== Conditional jump or move depends on uninitialised value(s) 
==2649== at 0x8048542: main (in /home/student/workspace/tests/main) 
==2649== Uninitialised value was created by a stack allocation 
==2649== at 0x80484FA: main (in /home/student/workspace/tests/main) 
==2649== 
Quit 
==2649== 
==2649== HEAP SUMMARY: 
==2649==  in use at exit: 0 bytes in 0 blocks 
==2649== total heap usage: 0 allocs, 0 frees, 0 bytes allocated 
==2649== 
==2649== All heap blocks were freed -- no leaks are possible 
==2649== 
==2649== For counts of detected and suppressed errors, rerun with: -v 
==2649== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6) 

順便說一句,我編譯此代碼優化OFF(-O0)。 我有2個問題:

錯誤原因是什麼:條件跳轉還是移動取決於未初始化的值?

爲什麼valgrind不顯示導致此錯誤的行的行號?

+0

如果你仍然想知道爲什麼沒Valgrind的不報告行號,你可以發佈你傳遞給gcc的完整命令行嗎?猜測,你可能會缺少'-g' – simonc

回答

2

不能保證fgets會正好寫入sizeof(command_line)字節到command_line。如果用戶鍵入一個較短的字符串,檢查

command_line[sizeof(command_line) - 2] != '\n' 

將讀取的command_line一部分不是由你的代碼初始化或fgets寫入。

有幾種方法可以解決這個問題。

您可以測試strlen第一提領的command_line

if (strlen(command_line) == NUM_CHAR + 1 && 
    command_line[sizeof(command_line) - 2] != '\n') 

年底前或者你可以初始化所有的command_line你把它聲明

char command_line[NUM_CHAR + 2]; 
memset(command_line, 0, sizeof(command_line)); 
相關問題