【问题标题】:Why do I get the segmentation fault error (arrays as elements of classes)?为什么会出现分段错误错误(数组作为类的元素)?
【发布时间】:2016-03-18 14:11:20
【问题描述】:

我有一个名为 Item 的类,它存储一个在编译时已知大小的数组:

class Item
{
  int *data;
public:
  Item(int array[], int length)
  {
    std::copy(array, array + length, data); // Line A
  }
};

在我的示例中,大小等于 1,但对于我的项目,我也需要更大的值。这是一个存储两个 Item 的类 Box。我不想在构造函数中有两个参数,所以我传递了一个大小为 2 的数组(因为该类只能存储 2 个 Item 并且每个都存储一个长度为 1 的数组)。

class Box
{
  Item *item1;
  Item *item2;
public:
  Box(int (&array)[2])
  {
    item1 = new Item(array, 1);
    item2 = new Item(array + 1, 1);
  }
  ~Box()
  {
    delete item1;
    delete item2;
  }
};

这就是我如何创建一个指向 Box 对象的指针:

int main()
{
  int tab[] = {8, 9};
  Box *box = new Box(tab);
  delete box;
  return 0;
}

运行上面这段代码后,出现如下错误:

分段错误(核心转储)。

我调试了它,结果发现是 A 行导致了问题。我还在我的主函数中创建了 Item 类,它没有给我任何错误。

在我看来,我正在尝试访问我的表之外的一些内存,但这不可能是真的 - 我只想复制我的数组的一个元素。此外,c++ 编译器也不会介意。

那么,我做错了什么?我该如何解决?

我正在使用 g++ 编译器和 -std=c++11 选项。

我可以改用 std::array,但出于好奇,我想知道我犯了什么错误。

【问题讨论】:

  • 你从不初始化指针data
  • 你永远不会为Item::data分配内存,至少你不会显示代码。
  • 我有,我忘记展示了。它现在有效,但我原来的问题没有解决。无论如何,谢谢。
  • 你为什么要使用所有这些指针?我真的认为不需要 any 指针使用构造函数初始化列表,std::vectorstd::array,您可以摆脱所有这些指针,而不必担心这样的问题(以及由于使用指针而遇到的更多问题。
  • 请不要在您的问题中编辑答案。

标签: c++ arrays class segmentation-fault runtime-error


【解决方案1】:

Item 不太对。当你有:

std::copy(array, array + length, data); // Line A

您实际上从来没有首先为data 分配任何东西——所以当它被初始化时,您正在写入该指针中碰巧出现的任何垃圾。您需要先执行以下操作:

data = new int[length];
std::copy(array, array + length, data);

虽然那时你记得添加一个析构函数,并复制/移动分配。更好的是简单地使用标准提供的内容:

using Item = std::vector<int>;

此外,c++ 编译器也不会介意。

仅仅因为代码编译并不意味着它可以工作。编译为我们捕获了很多错误,但它不能包罗万象!

【讨论】:

    【解决方案2】:

    表达式new int(length) 只分配一个单个 int 并将其初始化为lenght 的值。

    您需要使用方括号[] 来表示大小:new int[length]

    【讨论】:

    • 我认为这是 OP 错误地将我的答案复制到问题中 - 它最初不存在,我只是将其回滚(抱歉)。
    猜你喜欢
    • 2011-04-23
    • 2018-01-07
    相关资源
    最近更新 更多