C++ 将std::list转换为char*[size]

C++ 将std::list转换为char*[size],c++,C++,由于某些原因,我无法解释,字符数组中的每一项……都等于添加到其中的最后一项……例如,PROGRAGS[0]到PROGRAGS[size]包含最后一项的值 我一辈子都不知道自己做错了什么。有什么建议吗 int count = 0; char *progArgs[commandList.size()] for(list<string>::iterator t=commandList.begin(); t!=commandList.end(); t++) {

由于某些原因,我无法解释,字符数组中的每一项……都等于添加到其中的最后一项……例如,PROGRAGS[0]到PROGRAGS[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++;
    }
int count=0;
char*progArgs[commandList.size()]
for(list::iterator t=commandList.begin();t!=commandList.end();t++)
{
char item[strlen((*t).c_str())];//创建字符串
strcpy(item,(*t).c_str());//从常量字符转换为字符
progArgs[计数]=项目;
计数++;
}
编辑:


谢谢大家的快速回复…我知道你在说什么了

progArgs
是指向char的指针数组

您可以将这些指针中的每一个都设置为指向
item
是循环中的局部变量,因此一旦循环退出,
item
就不再存在,指针也不再有效[*]。但是,在C++实现中,它们仍然指向栈中的数组“代码<代码>项目/代码>”的内存位。此内存包含上次使用的内容,即列表中最后一个字符串的字符序列

如果要将字符串列表复制到数组中,最好使用字符串数组:

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::string progArgs[commandList.size()]//如果您的编译器有C99 VLA作为扩展名
整数计数=0;
对于(std::list::iterator t=commandList.begin();t!=commandList.end();++t){
程序参数[计数]=*t;
++计数;
}
或者更好地使用向量而不是数组:

std::vector<std::string> progArgs(commandList.begin(), commandList.end());
std::vector progArgs(commandList.begin(),commandList.end());
[*]更准确地说,
item
的范围是循环的单个重复,它名义上是“创建”和“销毁”的。但这并没有任何作用——在C++实现中,每次都重复使用相同的内存区域,并且不需要创建或销毁堆栈上的字符数组。

< p>您将相同的指针(栈数组的第一个元素<代码>项目> /代码>)分配给<代码> PrimARGs<代码>的每个元素,然后重复地覆盖那个内存。你可以做:

progArgs[count] = strdup(t->c_str());
去掉身体的前两行


strdup
分配内存,因此以后必须使用
free
释放每个元素。另外,您没有为NUL终止符分配字符。您需要将
strlen
+1。但是,这不是strdup的问题,因为它为您分配资源。

您每次都将
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++;
}
int count=0;
char*progArgs[commandList.size()]
for(list::iterator t=commandList.begin();t!=commandList.end();t++)
{
char*item=new char[strlen((*t).c_str())+1];//创建新字符串
strcpy(item,(*t).c_str());//从常量字符转换为字符
progArgs[计数]=项目;
计数++;
}
然后记得为progArgs中的每个元素调用
delete[]


就我个人而言,我会创建一个
string
数组,并根据需要动态转换为
char*

char数组
是局部变量,仅在
for
循环中可用

而是动态地分配它。

你说得对:

for(list<string>::iterator t=commandList.begin(); t!=commandList.end(); t++)
{
    char item[strlen((*t).c_str())]; //create character string
…这个右括号标志着它的作用域的结束。这意味着您要创建一个字符串,将其放入数组中,然后在添加下一个字符串之前销毁它。由于您在堆栈上创建了所有字符串,因此您创建的每个新字符串都是在与前一个完全相同的位置创建的,因此,在所有创建的最后,您有一组相同的字符串也就不足为奇了


如果您能告诉我们您在这里想要完成什么,也许会更好,这样我们可以帮助您完成。

项的作用域位于循环的局部。因此,
propArgs
数组包含一组基于堆栈的指针,可能都是相同的。您可以在调试器中检查它是如何工作的,只需在循环中单步执行两次,就应该清楚发生了什么

退出循环时,由公共指针寻址的缓冲区包含最近复制的
c_str()

你可以通过这样做来解决这个问题

char* item = new char[strlen((*t).c_str()) + 1];
但是,在退出循环时,您必须删除[]所有
propArgs
数组项


这段代码显示了对内存管理的基本理解不足,因此在重构代码之前进一步阅读可能会有用。如果此处使用的代码仅在比本例稍微复杂的上下文中,那么它可能会崩溃,因为在循环之外对
propArgs
的任何访问都将依赖于无效(不再在范围内)的

,除了其他内容之外,
strlen((*t).c_str())
可以替换为
t->size()
。建议的修复程序与原始修复程序一样具有一个off by一。复制到char*数组中对于调用预期的C API非常有用,例如UNIX/Linux execv(…),execvp()。@Tony:是的,但这并不排除使用
向量存储复制的字符串数据。也就是说,如果
char*
数组只用于调用exec,然后立即被丢弃,我认为根本没有必要复制字符串。
exec
函数实际上并没有修改字符串数据,它们只是出于历史原因而采用非常量,因此对于这种用法,您可以
const\u cast
使用
c\u str()
的结果。为了避免复制几个字符串,我想这有点小技巧。我想在
exec
的情况下,您不需要释放内存,因为进程即将被替换,所以关于RAII的良好实践是不相关的……我看您已经放弃了
char* item = new char[strlen((*t).c_str()) + 1];