内存违规:SIGSEGV 和“找不到虚拟 table... 的链接器符号”
Memory violation: SIGSEGV and 'can't find linker symbol for virtual table...'
我在 C++ 代码中遇到内存冲突错误,这让我抓狂。我必须使用一些现有的 classes,它们几乎在其他任何地方都可以正常工作。
我正在尝试制作自定义数组对象的副本,而不是稍后修改内部值。但是那个复制操作有问题...
症状如下:
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
但问题仍然存在,只是出现在不同的位置。
这是 'legacy' classes 中的一个:
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>
class 的某个深处,在哪里并不重要,因为总是像这里一样在 new
行中发生,并且总是没有明显的原因)
好吧,有件事没有引起我的注意...
过度索引数组主要发生在索引超出范围时。有时数组太短,或者索引太长,或者您创建了错误大小的数组。而最后一个案例就发生在这里。
我之所以回答这个问题是因为:
我已经看到引用的警告消息,但在完全不同的情况下(真正的链接问题,当节点实际上从 vtable 中丢失时)。在我的例子中,由于一些错误的数组处理,虚拟 table 被覆盖,令人惊讶。
Just for the future googlers, this can useful to debug a SIGSEGV which
appears at a weird location.
我学到了什么:
始终仔细检查容器对象(不仅仅是索引变量)
三重检查 提出新问题时引用的来源(是的,该问题在关键行中包含错字)
这里是解决方案,不是那么重要,但为了完整性...
ic
的值是 'bad guy',需要深入我的项目才能发现它,但我会解释它:
int ic = followingItems.length(); // where Arra<int> followingItems(x);
followingItems
是项目ids(Arra<
int>
的列表) 需要插入。
x
可以在 [1, allItemCount]
范围内
在Box
class中,Array<bool> items
是一个布尔掩码,用于标记一个项目是否在盒子里。显然,items.length() = allItemCount
所以:
followingItems.length <= allItemCount
首先,我意识到 ic
在 87
之前是 运行 而不是 400
。我想复制全部内容,但只测试并添加了前 87 项。
考虑到这一点,我发现了主要错误:
Box box(ic, capacity);
第一个参数应该是所有项目的数量,但又是 87 而不是 400。好吧,这很痛苦...
我在 C++ 代码中遇到内存冲突错误,这让我抓狂。我必须使用一些现有的 classes,它们几乎在其他任何地方都可以正常工作。
我正在尝试制作自定义数组对象的副本,而不是稍后修改内部值。但是那个复制操作有问题...
症状如下:
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
但问题仍然存在,只是出现在不同的位置。
这是 'legacy' classes 中的一个:
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>
class 的某个深处,在哪里并不重要,因为总是像这里一样在 new
行中发生,并且总是没有明显的原因)
好吧,有件事没有引起我的注意... 过度索引数组主要发生在索引超出范围时。有时数组太短,或者索引太长,或者您创建了错误大小的数组。而最后一个案例就发生在这里。
我之所以回答这个问题是因为:
我已经看到引用的警告消息,但在完全不同的情况下(真正的链接问题,当节点实际上从 vtable 中丢失时)。在我的例子中,由于一些错误的数组处理,虚拟 table 被覆盖,令人惊讶。
Just for the future googlers, this can useful to debug a SIGSEGV which appears at a weird location.
我学到了什么:
始终仔细检查容器对象(不仅仅是索引变量)
三重检查 提出新问题时引用的来源(是的,该问题在关键行中包含错字)
这里是解决方案,不是那么重要,但为了完整性...
ic
的值是 'bad guy',需要深入我的项目才能发现它,但我会解释它:
int ic = followingItems.length(); // where Arra<int> followingItems(x);
followingItems
是项目ids(Arra<
int>
的列表) 需要插入。
x
可以在 [1, allItemCount]
在Box
class中,Array<bool> items
是一个布尔掩码,用于标记一个项目是否在盒子里。显然,items.length() = allItemCount
所以:
followingItems.length <= allItemCount
首先,我意识到 ic
在 87
之前是 运行 而不是 400
。我想复制全部内容,但只测试并添加了前 87 项。
考虑到这一点,我发现了主要错误:
Box box(ic, capacity);
第一个参数应该是所有项目的数量,但又是 87 而不是 400。好吧,这很痛苦...