簡體   English   中英

C結構中的C ++字符串,這是非法的嗎?

[英]c++ string in C struct, is it illegal?

struct run_male_walker_struct {
        string male_user_name;
        string show_name;
};
typedef struct run_male_walker_struct run_male_walker_struct_t;

在另一個功能中:

run_male_walker_struct_t *p = malloc(sizeof(struct run_male_walker_struct));

問題,這是非法的嗎? 由於字符串是一個類,因此其大小不能由sizeof()確定。

不太清楚您在這里要問的是什么...要清楚一點, struct關鍵字是一個有效的C ++名稱,除了默認的保密性外,它的功能幾乎與class相同。 因此,如果您使用g ++進行編譯,並且包括字符串庫,那么這是一條有效的語句。

但是,使用malloc()調用只會給您內存,而不是實際上在該struct中構造值。 您可以通過調用默認構造函數來更適當地實例化它。

這是非法的,但不是出於您的考慮原因。

std::malloc() / std::free()new / delete之間的區別在於,后者將調用構造函數/析構函數,而前者則不會。 表達方式

void* p = std::malloc(sizeof(run_male_walker_struct))

將返回未初始化的內存塊,在該內存上未調用構造函數。 您不應用十英尺的桿子碰它-除了在其上調用構造函數外:

run_male_walker_struct* pw = new(p) run_male_walker_struct;

如果執行此操作,則也必須執行相反的操作:

pw->~run_male_walker_struct();

在釋放內存之前:

std::free(p);

但是,這留下了一個問題,為什么要這樣做。
這樣做的唯一原因應該是當您要將內存分配與構造分離時(例如,在池分配器中)。 但是,如果需要,最好將其隱藏在某些界面后面。 一個自然的做法是按類重載newdelete 同樣, std::vector在內部執行此操作。

結構定義本身很好。 結果是一個非POD聚合。 但是您應該更喜歡使用newdelete不是mallocfree因為它們可以正確處理構造和破壞。 如果要繼續使用malloc和free,則必須使用newplacement正確構造對象並在釋放對象之前手動調用析構函數以銷毀它:

#include <new>
...
run_male_walker_struct *p = (run_male_walker_struct*)
    malloc(sizeof(run_male_walker_struct));
new(p) run_male_walker_struct; // <-- placement-new
...
p->~run_male_walker_struct(); // <-- pseudo destructor call
free(p);

或者簡單地:

run_male_walker_struct *p = new run_male_walker_struct;
...
delete p;

順便說一句:C ++中不需要typedef

如果您使用的是C ++,請盡量不要使用malloc。 使用NEW是更好的選擇,當您瀏覽NEW()代碼時,您將意識到它確實調用了malloc!

使用NEW的優點是它將實例化您的類的構造函數。

另一個小意見,您提供的代碼不可編譯:

run_male_walker_struct_t *p = malloc(sizeof(struct run_male_walker_struct));

應該

run_male_walker_struct_t *p = (run_male_walker_struct_t*)malloc(sizeof(struct run_male_walker_struct));

這是由於malloc將返回void *。

使用malloc()可以,但是使用它只會為您的結構創建足夠的空間。 這意味着您將無法正確使用字符串,因為它們不是使用其構造函數初始化的。

請注意,字符串類的內容不在堆棧內存中,而是在動態內存中,這不會影響結構的大小。 所有類和結構都具有靜態大小,在編譯時就知道(如果定義了結構/類)。

我建議使用新的。 使用malloc 填充字符串。

這就提出了一個我自己的問題,構造函數是如何在C中動態分配的實例化上調用的(C中沒有構造函數之類的東西?)。 如果是這樣,則反對使用純C的另一個原因。

我相當確定這是合法的,因為即使不知道字符串的長度,std :: string對象的大小也將是已知的。 結果可能不是您期望的,因為malloc不會調用構造函數。

嘗試這個:

std::string testString1("babab");
std::string testString2("12345678");
std::string testString3;
std::cout <<" sizeof(testString1)" <<sizeof(testString1) << std::endl;
std::cout <<" sizeof(testString2)" <<sizeof(testString2) << std::endl;
std::cout <<" sizeof(testString3)" <<sizeof(testString3) << std::endl;

在我的機器上,這給了我以下輸出:

 sizeof(testString1)8
 sizeof(testString2)8
 sizeof(testString3)8

還有一些您不使用的原因:

run_male_walker_struct_t *p = new(struct run_male_walker_struct);

這是在c ++中執行此操作的正確方法,使用malloc幾乎可以肯定是一個錯誤。

編輯:有關C ++中的新vs malloc的詳細說明,請參見此頁面: http : //www.codeproject.com/KB/tips/newandmalloc.aspx

怎么樣

run_male_walker_struct_t * p = new run_male_walker_struct_t:

答案取決於您所說的“ C結構”的含義。

如果您的意思是“在C語言下有效的結構”,那么答案顯然是:它包含無效的C數據類型,因此該結構本身也無效。

如果您的意思是C ++ POD類型,則答案是否定的,這不是非法的,但是struct不再是POD類型(因為要成為POD,其所有成員也必須是POD,並且std::string不是)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM