【问题标题】:C++ Seg Fault at end of function. Reference line = closing brace函数结束时的 C++ 段错误。参考线 = 右大括号
【发布时间】:2012-10-16 03:02:52
【问题描述】:

总结:非常感谢大家!下面发布的所有回复都是正确的。最初的错误是我忘记为 NULL 终止符留出空间。 strcpy() 是一个危险的函数,因为当我使用它时,它不知道“字符串”的结尾是什么时候。因此,strcpy() 抓取了大量数据并覆盖了返回地址。

编辑:从程序中添加了更多代码

已解决:老实说,我最初的实现很垃圾。如果我想交换数组的元素,我什至不知道为什么要这样写交换。 (当时,每个元素中只有一个 char 数组。所以我能够摆脱旧的实现)。我已将其重写为:

void swap(ArrayElement list[], int index1, int index2) {
     ArrayElement temp;
     temp = list[index1];
     list[index1] = list[index2];
     list[index2] = temp;
}

我在以下函数结束时遇到分段错误问题。

struct ArrayElement {
    char data[SIZE_OF_ELEMENT];
    // Implemented this way so that I can expand to multiple values later on
}

//In main:
ArrayElement* list = new ArrayElement[NUM_OF_ELEMENTS];

void swap(ArrayElement list[], int index1, int index2) {
     char temp[SIZE_OF_ELEMENT];
     strcpy(temp, list[index2].data);
     strcpy(list[index2].data, list[index1].data);
     strcpy(list[index1].data, temp);
}

错误是第 45 行的分段错误,这是函数的结束大括号。这是使用 g++ 编译的。我使用 gbd 尝试调试它,一切正常,直到它碰到花括号。

如果需要,我可以从程序中提供更多代码。我不想发布整个内容,因为这是针对课程的。

【问题讨论】:

  • std::swap(list[index2].data, list[index1].data) 这对你有用吗,只是出于好奇。
  • 您应该至少显示调用函数的上下文以及ArrayElement 是什么...
  • 你试过你的调试器了吗?
  • @JimBalter - 仅当 .data 是一个数组时。如果是char*,你的建议是错误的。
  • @Robᵩ 是的……我写的很仓促。

标签: c++ arrays segmentation-fault curly-braces strcpy


【解决方案1】:

我的最佳猜测是,list[index2].data 处的字符串大于temp[],通过复制,您覆盖了堆栈和返回地址。

尝试插入长度测试:

#include <iostream>

...
int n = strlen(list[index2].data);
std::cerr << "len=" << n << ", SIZE_OF_ELEMENT=" << SIZE_OF_ELEMENT << std::endl;

看看n (list[index2].data) 是否大于SIZE_OF_ELEMENT

【讨论】:

  • 你是对的。我得到了 len=240 和 SIZE_OF_ELEMENT=30。我不明白这会怎样。 (我在原始帖子中添加了更多代码)。在使用我自己的测试数据之前,这个实现已经奏效了。当我使用讲师提供的文件时,此错误开始发生。我将重写 swap 以使 temp 成为 ArrayElement 对象并使用 '=' 进行交换...让我们看看它是否有效:)
  • 感谢您帮助我解决了我的问题。如果您想了解错误的结论,我将其添加到原始帖子的顶部。
【解决方案2】:

数据是这样定义的char data[SOME_CONSTANT]吗?如果是这样,那么您确定 SIZE_OF_ELEMENT 足够大吗?你也记得 NULL 终止符,

如果 ArrayElement 中的数据是这样定义的 char *data; 并在稍后使用 malloc 分配,那么您确定 index1 有一个足够大的缓冲区来容纳 index2 中的数据,反之亦然?同样,您也记得 NULL 终止符,

【讨论】:

  • 我确实忘记了 NULL 终止符。那是最初的错误。谢谢你帮我解决我的问题。如果您想了解错误的结论,我将其添加到原始帖子的顶部。
【解决方案3】:

strcpy 是一个危险函数。如果输入字符串的长度为SIZE_OF_ELEMENT 或更多,您将写到temp 数组的末尾。如果必须使用固定大小的数组作为strcpy 中的输出数组,则应在使用该函数之前测试strcpy 是否有效。

更好的是从使用char 数组切换到std::string

【讨论】:

  • 感谢您帮助我解决了我的问题。如果您想了解错误的结论,我将其添加到原始帖子的顶部。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-10-21
  • 2019-04-18
  • 1970-01-01
  • 2018-05-22
  • 2019-03-15
  • 2018-03-09
  • 2015-03-31
相关资源
最近更新 更多