开发者

vector of char stars in c++

If I declare a vector as such:

vector<char *> charStarVec(4);

and then add values to it like so:

charStarVec.at(0) = (char *) "one";
charStarVec.at(1) = (char *) "two";
charStarVec.at(2) = (char *) "three";
charStarVec.at(3) = (char *) "four";

Then no problems result. (I can print out all the vector elements just fine.)

But I get problems if I use character arrays (to get the data off the disk.)

The program crashes if I try to memcpy/strcpy/assign from a character array to a character pointer.

char *c = "blah";
char carr[5];
...
c[0] = carr[0];           //FAIL (crashes at runtime)
memcpy(c,carr,5);         //FAIL (crashes at runtime)
strcpy(c,carr,5);         //FAIL (crashes at runtime)
...
charStarVec.at(i) = carr; //FAIL (all 4 elements are the same as the last element.)
charStarVec.at(i) = c;

But how else am I supposed to get a v开发者_JAVA百科ector of character pointers to data that is a copy of what was on the disk, which is variable sized and may not terminate in a null character, thus requiring me to manually add the null character.

I am fairly new to c/c++, in case it wasn't obvious.


What do you think this line does?

char *c = "blah";

What it actually does is create a pointer, called c. This pointer points to a string literal, which is a read-only array, containing the bytes "blah" plus a NUL terminator.

String literals cannot be modified, so memcpy(c,carr,5) is undefined behavior.

If you always use const char* pointers for string literals, then your compiler will prevent you doing this. Unfortunately, for 25-year-old legacy reasons, C++ allows a char * to point to a string literal without an explicit conversion.

To actually solve your problem:

std::vector<std::string> vec(4);
vec[0] = std::string(carr, 5);

There is then no need for carr to contain a NUL terminator, because of how std::string works. You can get a const char* pointer with vec[0].c_str().

If you absolutely need a non-const char*, then use a vector<vector<char> > instead of a vector<string>.


Here are two reasonable routes. Use the std::string class instead of char pointers, or use strdup(...) to copy the array to a newly allocated char* pointer once you've loaded and null terminated it:

charStarVec.at(4) = strdup(carr);

You'll have to free(...) each pointer when you're done, or you'll leak memory.


It seems as thought you still need to read up on some basics of C, such as dynamic memory allocation. In your example, creating a pointer (char* c) does not actually allocate any memory, you need to do that explicitly.

char *c;         //the variable c is defined, but its value is un-initialised
c = NULL;        //c now points to NULL
c = new char[5]; //an array of 5 char's is allocated, and c is set to point to that array

//...

c[0] = carr[0];     
memcpy(c,carr,5);   
strcpy(c,carr,5);   

//...

charStarVec.at(i) = c;


You haven't allocated any memory at c, http://www.cplusplus.com/reference/clibrary/cstdlib/malloc/


c potentially refers to read only memory, you shouldn't assign anything to the block of characters it points to.

Also, strcpy(c,carr,5); is one character too many, because of the NUL terminator.

Finally, this should have bene definitely tagged as homework!

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜