malloc.c:3097: sYSMALLOc:断言在动态创建的对象的构造函数中失败
malloc.c:3097: sYSMALLOc: Assertion fails inside constructor of dynamically created object
我对 OOP C++有点陌生,所以我希望我只是犯了一些简单的初学者错误。我有一些代码给了我看似莫名其妙的malloc错误。我已经将我的代码简化为仍然崩溃的最小内容,即:
我的类.cpp:
#include <vector>
using std::vector;
#include <string>
using std::string;
class MyClass{
string * myString1;
string * myString2;
int length1;
int length2;
vector< vector<int>* > * myVector;
public:
MyClass(string * a, string * b);
};
MyClass::MyClass(string * a, string * b)
: myString1(a), myString2(b)
{
// commenting both of the lines that access the string sizes
// makes it work
length1 = myString1->size();
// commenting either or both of the following lines makes
// it work
length2 = myString2->size();
myVector = new vector< vector<int>* >;
}
MyClass.h
#ifndef MyClass_H
#define MyClass_H
#include <string>
using std::string;
class MyClass{
public:
MyClass(string * a, string * b);
};
#endif
测试.cpp:
#include "../include/MyClass.h"
#include <string>
using std::string;
int main()
{
string * A = new string("foobar");
string * B = new string("foobaz");
MyClass * mc = new MyClass(A, B);
return 0;
}
我像这样编译:
g++ -ggdb -Wall -c src/test.cpp -o .objects/test.o
g++ -ggdb -Wall -c src/MyClass.cpp -o .objects/MyClass.o
g++ .objects/test.o .objects/MyClass.o -ggdb -Wall -o test
当我运行它时,我得到这个:
test: malloc.c:3097: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Aborted
我已经看到 valgrind 被建议作为调试此类问题的工具,但我无法从它的输出中理解任何东西。输出很长,所以我把它粘贴在这里。
Gdb 指出创建新向量的行是问题所在(这并不太令人惊讶(。完整的 gdb 输出在这里。我觉得奇怪的是,如果我不访问任何一个字符串长度,那么新向量就会毫无问题地创建。
我在这里真的很茫然,任何帮助将不胜感激!
主要问题是你以两种不兼容的方式定义了MyClass
:在MyClass.cpp
中,它有五个数据成员(两个指针、两个整数和另一个指针(,但在MyClass.h
中,因此在test.cpp
中,它根本没有数据成员。因此,当您的main
函数调用new MyClass(A, B)
时,系统只为MyClass
的无数据成员版本分配足够的内存,然后调用构造函数,该构造函数初始化您未为其分配内存的数据成员。
你需要将类定义从MyClass.cpp
移动到MyClass.h
,并且MyClass.cpp
的第一行应该是#include "MyClass.h"
。这将确保您没有任何不兼容,因为如果您这样做,MyClass.cpp
将导致 发出编译错误。
你已经声明了两个完全不同的MyClass
版本;一个在MyClass.h
,另一个在MyClass.cpp
。test.cpp
中的 main()
函数会看到 MyClass.h 中的版本,并根据该定义分配内存,但 MyClass.cpp 中的代码正在处理该类的不同定义。
失败的原因是这两个定义在内存中具有不同的大小和布局。
要正确地执行此操作,您需要在MyClass.h中包含MyClass的完整定义。即
#ifndef MyClass_H
#define MyClass_H
#include <string>
using std::string;
class MyClass {
string * myString1;
string * myString2;
int length1;
int length2;
vector< vector<int>* > * myVector;
public:
MyClass(string * a, string * b);
};
#endif
这是C++的关键点之一 - 即使是私有成员也需要在可公开访问的类定义中。
然后你需要在MyClass.cpp
和test.cpp
中包含MyClass.h
,并从MyClass.cpp
中删除MyClass
声明——你只希望类声明出现在一个地方。
您
还有内存泄漏,因为您没有MyClass
析构函数提供析构函数,它将在其中清理在其构造函数中分配的内存。到处写new
和delete
的更好方法是调查std::shared_ptr。
- 类中的 Arduino 对象构造函数设置垃圾值
- 编译错误:临时对象构造函数中缺少参数
- 双指针在使用 new 时不调用对象构造函数
- 以支持继承的方式将自身shared_ptr添加到对象构造函数中的向量中
- 在创建对象向量时,不为每个对象唯一调用默认对象构造函数
- GCC __attribute__((constructor)) 在对象构造函数之前调用
- 自定义对象构造函数在循环外部循环
- 从全局对象构造函数停止监视器计时器
- Arduino 上的 Sketch 停止在对象构造函数中执行
- 通过在引用线程对象来传递取消引用的“this”指针来在函数对象构造函数中创建线程是好是坏
- 为什么当对象构造函数投入新表达式时,为什么不调用DealLocation函数
- 临时结构对象构造函数奇数调用
- 未显式引用对象的全局对象构造函数在最终二进制文件 - LD 中被丢弃
- 为什么 Clang++ 不在另一个静态库中运行全局对象构造函数?
- 在未加载上下文的情况下在对象构造函数中使用OpenGL函数
- 为什么我们需要一个用户提供的const对象构造函数
- 对象构造函数的C++数组
- 将子结构值设置为对象构造函数中安全的纯虚拟函数返回的值
- C等价于新对象(构造函数)
- C++:直接在参数列表中使用数组文字的对象构造函数