如果我声明一个向量:
vector<char *> charStarVec(4);
然后像这样添加值:
charStarVec.at(0) = (char *) "one";
charStarVec.at(1) = (char *) "two";
charStarVec.at(2) = (char *) "three";
charStarVec.at(3) = (char *) "four";
然后没有问题的结果。 (我可以打印出所有的矢量元素。)
但是如果我使用字符数组(从磁盘上获取数据),我会遇到问题。
如果我尝试从字符数组中将memcpy / strcpy / assign分配给字符指针,程序就会崩溃。
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;
但是我还应该如何得到一个数据字符指针向量,它是磁盘上的内容的副本,它是可变大小的,可能不会以空字符结尾,因此需要我手动添加null字符。
我对c / c ++很新,以防它不明显。
答案 0 :(得分:3)
您认为这条线有什么作用?
char *c = "blah";
它实际上做的是创建一个名为c
的指针。该指针指向一个字符串文字,它是一个只读数组,包含字节“blah”加上一个NUL终止符。
无法修改字符串文字,因此memcpy(c,carr,5)
是未定义的行为。
如果你总是使用const char*
指针来表示字符串文字,那么你的编译器会阻止你这样做。遗憾的是,对于25年前的遗留原因,C ++允许char *
指向字符串文字而没有显式转换。
要真正解决您的问题:
std::vector<std::string> vec(4);
vec[0] = std::string(carr, 5);
由于carr
的工作原理,因此std::string
不需要包含NUL终结符。您可以使用const char*
获得vec[0].c_str()
指针。
如果您绝对需要非const char*
,请使用vector<vector<char> >
代替vector<string>
。
答案 1 :(得分:1)
似乎您还需要阅读C的一些基础知识,例如动态内存分配。在您的示例中,创建指针(char * c)实际上并不分配任何内存,您需要明确地执行此操作。
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;
答案 2 :(得分:1)
这是两条合理的路线。使用std :: string类而不是char指针,或者在加载后将strdup(...)复制到新分配的char *指针并将其终止:
charStarVec.at(4) = strdup(carr);
完成后你必须释放(...)每个指针,否则你会泄漏内存。
答案 3 :(得分:0)
答案 4 :(得分:-2)
c可能是指只读内存,不应该为它指向的字符块分配任何内容。
此外,由于NUL终结符,strcpy(c,carr,5);
是一个字符太多。
最后,这应该肯定被标记为作业!