[英]Converting a std::list to char*[size]
由于某种原因,我无法解释,字符数组中的每个项目...都等于添加到它的最后一个项目...例如,progArgs [0]到progArgs [size]包含最后一个项目的值。
我无法弄清楚自己一生中做错了什么。 有什么建议么?
int count = 0;
char *progArgs[commandList.size()]
for(list<string>::iterator t=commandList.begin(); t!=commandList.end(); t++)
{
char item[strlen((*t).c_str())]; //create character string
strcpy(item, (*t).c_str()); //convert from const char to char
progArgs[count] = item;
count++;
}
编辑:
感谢大家的快速反应...我明白你在说什么
progArgs
是一个指向char的指针数组。
您将每个指针都设置为指向item
。 item
是循环中的局部变量,因此一旦退出循环, item
就不再存在,并且指针也不再有效[*]。 但是,在您的C ++实现中,它们都仍指向内存中的位,该位曾经是堆栈上的数组item
。 该内存包含其最后一次使用的内容,即列表中最后一个字符串中的字符序列。
如果要将字符串列表复制到数组,则最好使用字符串数组:
std::string progArgs[commandList.size()] // if your compiler has C99 VLAs as an extension
int count = 0;
for(std::list<std::string>::iterator t=commandList.begin(); t != commandList.end(); ++t) {
progArgs[count] = *t;
++count;
}
甚至更好的是,使用向量而不是数组:
std::vector<std::string> progArgs(commandList.begin(), commandList.end());
[*]更准确地说, item
的范围是循环的单个重复,名义上每次都“创建”和“销毁”。 但这并没有做任何工作-在您的C ++实现中,每次都重复使用相同的内存区域,并且不需要在堆栈上创建或销毁char数组的工作。
您正在为progArgs
每个元素分配相同的指针(堆栈数组item
的第一个元素的地址),然后重复覆盖该内存。 你可以做:
progArgs[count] = strdup(t->c_str());
并摆脱for正文的前两行。
strdup
分配内存,所以你必须给每个元素有免费free
版本。 另外,您没有为NUL终止符分配字符。 您需要strlen
+1。但是,这不是strdup
的问题,因为它会为您分配。
item
作用域在循环本地。 因此, propArgs
数组包含一堆基于堆栈的指针,可能都一样。 您可以检查它在调试器中是如何工作的,只需循环两次即可,应该清楚发生了什么。
在退出循环时,公用指针寻址的缓冲区包含最近复制的c_str()
。
您可以通过执行此操作来解决此问题
char* item = new char[strlen((*t).c_str()) + 1];
但是,当您退出循环时,必须删除[]所有propArgs
数组条目。
此代码显示出对内存管理的基本了解,因此在重组代码之前进一步阅读可能会很有用。 如果此处使用的代码仅是比本示例稍微复杂的上下文,则它可能会崩溃,因为循环外对propArgs
任何访问都将依赖于无效(不再在范围内)的item
。
您progArgs[count]
都将progArgs[count]
设置为相同的项目!
int count = 0;
char *progArgs[commandList.size()]
for(list<string>::iterator t=commandList.begin(); t!=commandList.end(); t++)
{
char * item = new char[strlen((*t).c_str()) + 1]; //create new character string
strcpy(item, (*t).c_str()); //convert from const char to char
progArgs[count] = item;
count++;
}
然后记住为progArgs中的每个元素调用delete[]
。
就个人而言,我将创建一个string
数组,并根据需要即时转换为char *
。
char
数组item
是局部变量,仅在for
循环中可用。
而是动态分配它。
你是对的:
for(list<string>::iterator t=commandList.begin(); t!=commandList.end(); t++)
{
char item[strlen((*t).c_str())]; //create character string
...这确实会创建一个数组,但是会在堆栈上创建它,因此当到达其作用域的末尾时,它会被销毁。
strcpy(item, (*t).c_str()); //convert from const char to char
progArgs[count] = item;
count++;
}
...并且这个结束括号标志着它范围的结束。 这意味着您要创建一个字符串,将其放入数组中,然后在添加下一个字符串之前将其销毁。 由于您要在堆栈上全部创建它们,因此,您创建的每个新对象都将在与上一个完全相同的位置上创建,因此在最后,您有一堆这样的对象就不足为奇了相同的字符串。
如果您告诉我们您要在此处完成的工作,可能会更好,因此我们可以帮助您做到这一点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.