【问题标题】:segmentation fault while inserting into a set插入集合时出现分段错误
【发布时间】:2012-01-10 17:06:53
【问题描述】:

我写了一个示例程序:

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

谁能告诉我为什么?

【问题讨论】:

  • 你的调试器(例如,gdb 如果在 Linux 上)告诉你什么?
  • 哦,那些必须使用 C 的人的悲剧...
  • 我在开发 c++ 的 windows 上运行这个。调试器说故障是在第一次插入 set 期间。

标签: c++ stl set


【解决方案1】:
char *data;
strcpy(data,str[i]);

尝试将数据复制到未分配的指针并导致未定义行为
您的指针应该指向一个足够大的分配内存,以容纳您要复制到其中的数据。

理想的解决方案是在使用 C++ 编程时使用 std::string 而忘记 char *

【讨论】:

  • No while seg fault 调试是在第一次插入集合期间。
  • @peter: Undefined Behavior 的问题是所有的赌注都被取消了,你的程序可以显示任何随机行为,这就是你在这种情况下可以看到的。
  • @peter:或者它在 strtol 中,因为您尝试使用您尝试复制到未初始化指针的数据。相信 Als,他是对的。
  • 一旦您的代码遇到未定义的行为,一切都会发生。它根本不会崩溃,或者在该行之后任何地方都会崩溃。
  • @peter:是的,因为未定义行为现在不再存在。data 现在有足够的内存,可以在不调用 UB 的情况下复制字符串。我希望这能说服你。
【解决方案2】:

您必须分配数据才能保存复制的字符串:

 char *data; //unallocated
 strcpy(data,str[i]);

【讨论】:

    【解决方案3】:

    它应该在那里产生段错误:

    char *data;
         strcpy(data,str[i]);
    

    因为您正在将数据复制到您未分配的位置!如果你喜欢这样做“c-way”,你必须使用malloc

    或者你不使用char*,,而是使用std::string! (和 string.c_str() 如果你需要一个 char*)

    【讨论】:

    • 错误...malloc?在 C++ 中?祈祷为什么?为什么不new
    • "new char",我从来没有读过这个。如果您开始使用“strcpy”之类的函数,则必须使用 char[20] 或 char* c = malloc(c, 20); 进行内存管理。我知道这对 c++ 不利,但 str* 函数也是如此。
    • @AlokSave 必须是 new[]
    【解决方案4】:

    当您复制字符串以便使用 strtok 修改它时,您需要使用 std::vector&lt;char&gt;

    但是 strtok 不是标记字符串的理想方法,我建议改变策略。

    例如,您可以使用istringstream 对字符串进行标记,这样您就可以直接读取整数,然后在循环中读取分隔符,直到到达字符串的末尾。

    boost::tokenize 会为你做很多这样的工作,你可能想考虑使用它。

    顺便说一句,虽然它仍然可以编译以不破坏遗留代码,但您永远不应该将文字分配给char*,而应使用const char *。在这种情况下,您不会尝试修改它们。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-03-28
      • 2020-12-08
      • 2021-12-17
      • 1970-01-01
      • 1970-01-01
      • 2022-06-10
      • 2022-11-05
      • 2017-06-28
      相关资源
      最近更新 更多