开发者

Dynamically allocated C array of strings

I'm not clear why this should fail, and why it fails where it does:

std::string* s;
s = (std::string*)malloc(sizeof(std::string) * 10);
s[0] = "string0";
s[1] = "string1";
s[2] = "string2"; //Segmentation fault

It doesn't matter what the size of strings assigned to s[0] - s[2] are, or how much space is malloc'ed. The same thing happens with QStrings. I presume that the trouble arises from the fact that std::string contains an internal pointer, so sizeof() just returns the size of the pointer, but given that std::strings behave like values otherwise (=, ==, etc.) I don't see why that entails failure here.

Also, for compatibility with other code I need to use C arrays here, not e.g. st开发者_StackOverflowd::vector. And I'm looking for a general solution (that will work with QString, QDateTime, etc) if there is one. But I'd be happy just to know what's going on.

Edit: Got a downvote... What's wrong with this question? I did look around first for awhile (including SO), didn't find this addressed.


You can not malloc an array of class objects, because this function does not invoke any constructors. You just get memory filled with garbage, which you then try to reinterpret as an array of class objects.

Arrays of C++ objects are allocated with new[].

As to compatibility with other code, you probably can use std::vector, because &vec[0] gives you a pointer to the first element in a contiguous array.


If you insist on using malloc and free, then you'll need to manually invoke the constructor for each array item with placement new and manually invoke each destructor before freeing.


The problem is that std::string has a constructor that has to be called.

Not that having an array of strings is a good idea, but if you must:

string* s = new string[10];


The problem arises because you should not use malloc to allocate space for classes with constructors (like std::string) unless you really, really know what you are doing. Do it the easy way and use new

std::string* s;
s = new std::string[10];
s[0] = "string0";
s[1] = "string1";
s[2] = "string2";

The techinical reason for your code not working is that you haven't constructed any of your strings because you haven't called their constructors, all you've got is a block of uninitialised memory. On the other hand new does call the std::string constructor on the memory it allocates.


with malloc, the std::string's constructor is not called. That could be the reason. BTW, why are using malloc to allocate memory when you are using std::string ? What stops you in using new ?


As already mentioned:

You can not malloc an array of class objects, because this

function does not invoke any constructors. You just get memory filled with garbage, which you then try to reinterpret as an array of class objects.

If you want [ as a workaround ] do this:

char * s[10];

for (int i=0; i<10; i++) s[i] = new char[10];

strcpy(s[0], "string0");

strcpy(s[1], "string1");

strcpy(s[2], "string2");


What you probably want is a vector of strings:

std::vector<std::string> s(3);
s[0] = "string0";
s[1] = "string1";
s[2] = "string2";

Also, for compatibility with other code I need to use C arrays here, not e.g. std::vector

You can obtain a raw pointer to the first element for interop with legacy code:

string* p = &s[0];
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜