2011-08-21 54 views
0

有人可以告訴我爲什麼第一個程序崩潰,但第二個不是? 第一個(崩潰):調試爲什麼size_t不能用作數據成員?

#include <cstdlib> 
class test 
{ 
public: 
    test(const char *cstr) 
    { 
     size_t j=0; 
     while(cstr[n++]) 
      ; 
     //n = j; 
    } 
private: 
    size_t n; 
}; 

int main() 
{ 
    test("Hello, world!\n"); 
    return 0; 
} 

第二個不崩潰(使用局部變量構造函數,而不是數據成員數):

#include <cstdlib> 
    class test 
    { 
    public: 
     test(const char *cstr) 
     { 
      size_t j=0; 
      while(cstr[j++]) 
       ; 
      n = j; 
     } 
    private: 
     size_t n; 
    }; 

    int main() 
    { 
     test("Hello, world!\n"); 
     return 0; 
    } 

在Windows上運行的MinGW。 化妝:* [運行]錯誤-1073741819

回答

7

很簡單,因爲在你的第一個例子中,構造函數使用n以往任何時候初始化之前(實際上,n永遠不會被初始化)。

所以行

while(cstr[n++]) 

是不確定的行爲。

嘗試:

test(const char *cstr) : n(0) // <-- initialize n 
    { 
     size_t j=0; 
     while(cstr[n++]) 
      ; 
     //j = n; 
    } 
2

的私有成員爲size_t n的第一個例子是永遠不會初始化。它的值是未定義的。在while循環之前添加n = 0,它的工作原理應該是一樣的。

3

在第一種情況下,您正在使用未初始化的n,這就是您的程序崩潰的原因,這是未定義行爲(UB)的一種可能性。使用未初始化的變量調用UB。

test(const char *cstr) 
{ 
    size_t j=0; //<--- here you want to do : n = 0; 
    while(cstr[n++]) 
     ; 
    //j = n; 
} 

或者更好的是,你應該使用成員初始化列表如下:

test(const char *cstr) : n(0) 
{     //^^^^^^ it is member-initialization-list 
    while(cstr[n++]) ; 
} 

確保cstr是空值終止字符串,否則你的代碼還是會有UB。

相關問題