2011-09-22 151 views
2

我們如何初始化類的構造函數中的結構體指針。 例子:在類構造函數中初始化結構體

struct my_struct{ 
    int i; 
    char* name; 
}; 
class my_class{ 
    my_struct* s1; 
    my_class() { 
     // here i want to make s1->i = 10; and s1->name = "anyname" ; 
     // should i assign it like s1->i= 10; and call new for s1->name and strcpy(s1->name "anyname"); 
     // it compiles in g++ without any warning/error but gives seg fault at run time 
    } 
}; 

回答

-3
my_class() { 
    s1 = new (my_struct); 
    s1->i = 10; 
    s1->name = (char *) malloc(strlen("anyname")); 
    s1->name = "anyname"; 
    // here i want to make s1->i = 10; and s1->name = "anyname" ; 
    // should i assign it like s1->i= 10; and call new for s1->name and strcpy(s1->name "anyname"); 
    // it compiles in g++ without any warning/error but gives seg fault at run time 
    } 


~my_class(){ 
    free(s1->name); 
    delete s1; 
    } 
+0

至少你已經考慮過'name'的存儲空間了 - 這裏的一些其他答案還沒有... – Nim

+5

代碼是錯誤的。如果's-> name'的類型爲'char *',用行s1-> name =「anyname」賦值;'是做錯的方法,之後我懷疑執行會繼續沒有在'free(s1-> name)'這一行崩潰;'。正確的做法是使用'strpcy'或其一個變體。 – paercebal

+0

很可能這應該是's1-> name = strdup(...);'。 – hochl

2

由於這是C++,使用std::string代替char*

struct my_struct{ 
    int i; 
    std::string name; 
}; 
class my_class{ 
    my_struct* s1; 
    my_class() { 
     s1 = new my_struct; 
     s1->i = 10; 
     s1->name = "anyname"; 
    } 
}; 

原密碼segfaulted是,你無法爲s1分配內存和原因也未能分配內存s1->name。我已經使用new修復了前者,後者使用std::string修復了前者。如果由於某種原因,您不能使用std::string,請在您嘗試使用strcpy的地方使用strdup

最後,不要忘記爲my_class一個析構函數將刪除s1(和將釋放s1->name如果你選擇char*strdup)。

+0

請記住刪除析構函數中的s1指針(如果它必須是原始指針)。 – murrekatt

+0

感謝aix ...我明白了:)但是我仍然不確信爲什麼不在C++中使用char *。 – Ruchi

+0

用於提示'std :: string'。但爲什麼要停在這裏?我還會將'my_struct *'更改爲'std :: unique_ptr '。 – Henrik

3

當您創建my_class的實例時,s1指針不指向任何內容。你必須爲它分配內存,如下所示:

myclass() { 
    s1 = new my_struct; 
    // initialize variables 
} 

您還必須爲它創建一個析構函數:

~myclass() { 
    // delete variables 
    delete s1; 
} 

此外,由於這是C++,我建議你使用std::string代替char*秒。

+2

或更好的是,將's1'的定義更改爲'std :: auto_ptr s1'或'std :: unique_ptr s1'。那麼不需要在析構函數中刪除它。 – Praetorian

+0

std :: auto_ptr在C++ 0x中已棄用。因此,使用std :: unique_ptr – Vishal

+1

@Vishal:好的,但並非所有編譯器都提供對C++ 11的訪問。對於這些編譯器,如果是有限的,那麼'std :: auto_ptr'仍然是一個有效的解決方案。 – paercebal

0

我敢肯定你可以使用初始化列表,並且直接使用new + init結構體。另外,你可別忘了,你必須刪除指針時,即可大功告成:

struct my_struct{ 
    int i; 
    char* name; 
}; 
class my_class{ 
    my_struct* s1; 
    my_class() : s1(new my_struct) { 
     s1->i = 2; 
     s1->name = "Something"; 
    } 
    ~my_class() { delete s1; } 
}; 

此外,請確保您使用的是char*是有原因的,否則std::string通常都只有更好。

0

如果結構是類裏面,你可以使用結構構造函數:

struct my_struct 
{ 
    int i; 
    std::string name; 

    my_struct() 
    { 
    i = 10; 
    name = "anyname"; 
    }; 
}; 

如果它是全球性的,你首先需要創建對象,然後將其初始化:

class my_class 
{ 
    my_struct * s1; 
    my_class() : s1(new my_struct()) 
    { 
    s1->i = 10; 
    s1->name = "anyname"; 
    } 
}; 
14

我令人驚訝的是沒有人提出以下建議...

struct my_struct 
{ 
    int i; 
    std::string name; 

    my_struct(int argI, std::string const& argName) : i(argI), name(argName) {} 
}; 

class my_class 
{ 
    my_struct s1; // no need for pointers! 

    my_class() : s1(1, std::string("test name")) {} // construct s1 using the two argument constructor, can also default construct as well. 
}; 

使用這種方法,您不需要需要擔心清理s1,它是自動的...

+1

+1。 「我很驚訝,沒有人提出以下建議......」的確......我對這些答案中看到多少malloc /新聞感到震驚。 : - / – paercebal