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

时间:2010-09-15 01:59:40

标签: c++

由于某些原因我无法解释,字符数组中的每一项......等于添加到它的最后一项...例如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++;
    }

编辑:

感谢所有人的快速回复...我看到你在说什么

6 个答案:

答案 0 :(得分:3)

progArgs是一个指向char的指针数组。

您将每个指针设置为指向itemitem是循环中的局部变量,因此只要循环退出,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数组。

答案 1 :(得分:3)

您正在为item的每个元素分配相同的指针(堆栈数组progArgs的第一个元素的地址),然后重复覆盖该内存。你可以这样做:

progArgs[count] = strdup(t->c_str());

并摆脱身体的前两行。

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

答案 2 :(得分:1)

item具有循环的局部范围。因此propArgs数组包含一堆基于堆栈的指针,可能都是相同的。您可以在调试器中检查它是如何工作的,只需循环两次循环,它应该清楚发生了什么。

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

您可以通过执行

来解决此问题
char* item = new char[strlen((*t).c_str()) + 1];

但是当你退出循环时,你必须删除[]所有propArgs数组条目。

此代码显示了对内存管理的基本缺乏理解,因此在重构代码之前进一步阅读可能会有用。如果此处使用的代码仅比此示例稍微复杂一些,则它可能会崩溃,因为循环外propArgs的任何访问都将依赖于无效(不再在范围内)item。< / p>

答案 3 :(得分:0)

您每次都将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 *

答案 4 :(得分:0)

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

而是动态分配它。

答案 5 :(得分:0)

你是对的:

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++;
}

...而这个结束括号标志着其范围的结束。这意味着您正在创建一个字符串,将其放入您的数组中,然后在添加下一个字符串之前将其销毁。由于您在堆栈中创建了它们,因此您创建的每个新创建都与前一个创建完全相同,因此最后,您有一堆相同的字符串。

如果你告诉我们你在这里想要完成的事情,也许会更好,所以我们可以帮助你做到这一点。