2014-09-04 126 views
1

我運行代碼的valgrind未初始化值8

int fun(char* str) { 
    char* prt1; 
    char* ptr2; 
    char sstr[20]; 

    strcpy(sstr, "\0"); 

    ptr1 = str; 
    ptr2 = sstr; 

    while (((isspace(*ptr1)) || (iscntrl(*ptr1))) && (*ptr1 != '\0')) 
     ptr1++; 

    while (*ptr1 != '\0') 
     *ptr2++ = *ptr1++; 

    while (((isspace(*(ptr2 - 1))) || (iscntrl(*(ptr2 - 1)))) && (ptr2 > str)) 
     ptr2++; 

    *ptr2 = '\0' strcpy(str, (S8*)sstr); 

    return (strlen(ptr1)); 
} 

收到此錯誤使用尺寸8 的未初始化值的線路

while (((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))) && 
    (ptr2 > str)) 

如果我把NULLP分配給指針前檢查這是錯誤消失

if (ptr1 != NULLP && ptr2 != NULLP) { 
    ptr1 = str; 
    ptr2 = sstr; 
} 

它是否與Valgrind代碼錯誤或應該包括檢查?

感謝您的幫助。

+0

請不要寫'*(PTR-1)'當你的意思是,不執行'PTR [-1]'。你知道,我們可能會用完括號。 – unwind 2014-09-04 14:25:03

+0

添加空檢查後仍然存在循環*(ptr-1),爲什麼沒有錯誤? – user3679622 2014-09-04 14:28:15

+1

空檢查調用UB,並且之後所有事情都可能發生 – 2014-09-04 14:33:53

回答

1

我想如果你改變這一行:

while (((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))) && (ptr2 > str)) 

這樣:

while ((ptr2 > str) && ((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1))))) 

你不會得到錯誤。看起來你可能在 開始str之前讀取,因爲你的檢查ptr2 > str將發生在 取消引用之後。將此檢查移至條件的開頭允許 它短路。

+0

只有第一次檢查可以,在'ptr2 ++'之後,你仍然會檢查未初始化的字符 – 2014-09-04 14:30:00

+0

這段代碼似乎有多個問題,我現在注意到ptr2不是即使是一個指向str的指針(它指向sstr緩衝區)。 – ajclinto 2014-09-04 15:19:04

+0

沒關係我認爲有數據從'ptr1'複製到'ptr2',當然'ptr2> str'應該是'ptr2> sstr' – 2014-09-04 15:39:06

3

不檢查NULLP是完全錯誤的,實際上調用了未定義的行爲,因爲當時指針沒有被初始化。

真正的問題是,當你第一次進入循環

while (((isspace (*(ptr2-1))) || (iscntrl (*(ptr2-1)))) && (ptr2 > str)) 

你檢查的最後一個字符複製的,如果這就是你增加ptr2空格或控制字符,現在你檢查的第一個字符你從未初始化。 (擱置的事實條件也是不對的,你有沒有複製任何字符的情況。然後isspace(*(ptr2-1))將調用UB和)

如果要修剪sstr(會這樣呢?),你的迴路應

while (ptr2 > sstr && (isspace (ptr2[-1]) || iscntrl (ptr2[-1]))) 
    ptr2--; 

注意區別:

  • 比較ptr2sstr代替str,並首先做它,這樣isspace()和如果ptr2 == sstr
  • ptr2--而不是ptr2++