插入集合时出现分段错误

时间:2012-01-10 17:06:54

标签: c++ stl set

我写了一个示例程序:

#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));

谁能告诉我为什么?

4 个答案:

答案 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 *。在这种情况下,您不会尝试修改它们。