我写了一个示例程序:
#include<iostream>
#include<set>
#include<conio.h>
using namespace std;
int main()
{
set<int> myset[4];
char *str[4]={"1-2-3-4","3-4-34-3","7-45-35-3","67-45466-3633-3"};
for(int i=0;i<4;i++)
{
char *data;
strcpy(data,str[i]);
char *pch;
pch = strtok (data,"-");
for(int j=0;pch != NULL&&j<4;j++)
{
myset[j].insert((int)strtol(pch, NULL, 10));
pch = strtok (NULL, "-");
}
}
getch();
return 0;
}
此程序在
处发出分段错误myset[j].insert((int)strtol(pch, NULL, 10));
谁能告诉我为什么?
答案 0 :(得分:6)
char *data;
strcpy(data,str[i]);
尝试将数据复制到未分配的指针并导致未定义的行为。
您的指针应指向一个足够大的已分配内存,以容纳您要复制到其中的数据。
理想的解决方案是在使用C ++进行编程时使用std::string
并忘记char *
。
答案 1 :(得分:1)
您必须分配数据才能保存复制的字符串:
char *data; //unallocated
strcpy(data,str[i]);
答案 2 :(得分:1)
它应该在那里产生段错误:
char *data;
strcpy(data,str[i]);
因为您要将数据复制到您未分配的地方!如果你喜欢这样做“c-way”,你必须使用malloc
。
或者您不使用char*,
使用std::string
代替! (和string.c_str()如果你需要一个char *)
答案 3 :(得分:1)
当您复制字符串以便使用strtok进行修改时,您需要使用std::vector<char>
然而,strtok不是标记你的字符串的理想方式,我建议改变策略。
例如,您可以使用istringstream
来标记字符串,这样您就可以直接读取整数,然后读取循环中的分隔符,直到到达字符串的末尾。
boost::tokenize
会为您完成大量此项工作,您可能需要考虑使用它。
顺便说一下,虽然它仍然编译为不破坏遗留代码,但您永远不应该将文字分配给char*
,而是使用const char *
。在这种情况下,您不会尝试修改它们。