内存违规:SIGSEGV和'无法找到虚拟表的链接器符号...'

时间:2015-11-05 12:06:45

标签: c++ arrays memory segmentation-fault vtable

我在C ++代码中遇到内存冲突错误,这让我很疯狂。我必须使用一些现有的类,它们几乎在其他任何地方都能正常工作。

我正在尝试制作自定义Array对象的副本,而不是稍后修改内部值。但是复制操作有问题......

症状如下:

    复制后
  • Segmentation fault,但不是立即

  • 警告:can't find linker symbol for virtual table for 'MyClass<T>' value

MyClass<T>与有问题的部分无关,搜索后我发现当 vtable被覆盖 (link)时会出现此错误。

SIGSEGV出现在此片段的末尾:

// New boxes based on previous content, so first make a copy
Array<Box> nextBoxes(size);
int ic = followingItems.length();  // Array<int> followingItems() : some item id
for (int b = 0; b < size; ++b) {
    Box box(ic, capacity);
    const Box& oBox = currentBoxes[b];  // Array<Box> currentBoxes(size);
    for (int i = 0; i < ic; ++i) {
        if (oBox[i])
            box.add(i);
    }
    nextBoxes.add(box);
}

createConfig(nextBoxes, nextItems);
...
generateCostMatrix(nextBoxes, costMatrix); // <--[SIGSEGV] without any reason, variables are fine

那就是我完全迷失的地方。我尝试使用std::vector代替Array<Box> nextBoxes,但问题仍然存在,只是出现在不同的位置。

这是来自&#39;遗产&#39;类:

class Box 
{
    Array<bool> items;  // mask of all tools
    int capacity, itemCount, count;
public:
    Box();
    Box(int num, int cap)
      : items(num), capacity(cap), itemCount(num), count(0)
    {
        for (int i = 0; i < num; i++)
            items.add(false);
    }
    Box(const Box& value){...}
    ~Box(){...}
    ...

来自崩溃位置的微小调试器信息:

array = new T[maxlen]
// values: array=0x0, maxlen=30, len=0 --> looks OK

(在Array<T>课程的某个地方,它在哪里并不重要,因为这里总是发生在new行,并且总是没有明显的原因)

1 个答案:

答案 0 :(得分:1)

好吧,有些东西让我失去了注意力...... 当索引超出范围时,过度索引数组会发生。有时数组太短,或索引太长,或者您创建了错误大小的数组。最后一例发生在这里。

我回答这个问题的原因是:

我已经看到了引用的警告消息,但是在完全不同的情况下(真正的链接问题,当vtable中实际缺少节点时)。在我的情况下,由于一些糟糕的数组处理,虚拟表被覆盖了,并且令人惊讶。

  

仅限未来的googlers,这对于调试SIGSEGV非常有用   出现在一个奇怪的位置。

我学到了什么:

  • 总是仔细检查容器对象(而不仅仅是索引变量)

  • 当您提出新问题时,
  • 三重检查您引用的来源(是的,问题包含关键行中的拼写错误)

这是解决方案,这不是那么重要,但为了完整......

ic的价值是'坏人',需要深入我的项目来发现它,但我会解释它:

int ic = followingItems.length(); // where Arra<int> followingItems(x);

followingItems是需要插入的商品 ID Arra< int >)的列表。 x可以在[1, allItemCount]

范围内

Box类中,Array<bool> items是一个布尔值掩码,用于标记项目是否在框中。遗憾的是,items.length() = allItemCount所以:

followingItems.length <= allItemCount

首先,我意识到ic一直运行到87而不是400。我想复制完整的内容,但只测试并添加了前87项。 在我的脑海中,我发现了主要的错误:

Box box(ic, capacity);

第一个参数应该是所有项目的数量,但是再次是87而不是400。嗯,这很痛苦......