繁体   English   中英

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

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM