[英]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);
但是,這留下了一個問題,為什么要這樣做。
這樣做的唯一原因應該是當您要將內存分配與構造分離時(例如,在池分配器中)。 但是,如果需要,最好將其隱藏在某些界面后面。 一個自然的做法是按類重載new
和delete
。 同樣, std::vector
在內部執行此操作。
結構定義本身很好。 結果是一個非POD聚合。 但是您應該更喜歡使用new
和delete
不是malloc
和free
因為它們可以正確處理構造和破壞。 如果要繼續使用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.