我在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
行,并且总是没有明显的原因)
答案 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。嗯,这很痛苦......