动态数组和删除运算符的 boost::python 内存错误
Posted
技术标签:
【中文标题】动态数组和删除运算符的 boost::python 内存错误【英文标题】:boost::python memory error with dynamic array and delete operator 【发布时间】:2020-07-10 18:00:22 【问题描述】:我有这段代码用于测试 C++ 代码与原始 python 代码的速度(我使用指针数组来确保数据位于单个连续块中,因为向量必须在它增长时进行复制,这需要 O(N) 时间):
void MyClass::test_packet()
time_t t1;
time(&t1);
PacketInfo* packets;
for(int i = 0; i < 336000; i++)
for(int j = 0; j < 18; j++)
int N = 18;
// allocate memory for 18 objects in a continous block
packets = new PacketInfo[N];
// create the packetInfo objects
packets[i] = PacketInfo(i, i);
// free the 18 memory blocks
delete[] packets;
time_t t2;
time(&t2);
cout << "total time for 336000 * 18 packets : " << (t2 - t1) << "seconds" << endl;
BOOST_PYTHON_MODULE(MyClass)
class_<MyClass>("MyClass", init< /*parameter types go here */>())
// some other functions
.def("test", &MyClass::test_packet);
python 测试文件如下所示:
from MyClass import *
MyClass.test()
这给了我一个双重空闲或损坏的内存错误:
*** Error in `python3': double free or corruption (!prev): 0x00000000016b1b10 ***
我评论了 delete[] 运算符,但这给了我一个分段错误:
Erreur de segmentation (core dumped)
知道如何解决这个问题吗?
谢谢
【问题讨论】:
【参考方案1】:这里有一些不正确的代码
for(int i = 0; i < 336000; i++)
for(int j = 0; j < 18; j++)
int N = 18;
// allocate memory for 18 objects in a continous block
packets = new PacketInfo[N];
// create the packetInfo objects
packets[i] = PacketInfo(i, i);
如果 i
大于 18(显然会这样),那么 packets[i]
将是一个越界数组访问。
packets[j]
的替代方案没有多大意义,因为分配相对于循环的定位不正确(大概它应该在循环之前)。
另外你关于向量的说法是不正确的。
vector<PacketInfo> packets(18);
将分配一个大小为 18 的向量,其中包含 18 个连续元素,并且由于该向量没有增长,因此也不会重新分配。
查看代码中的 cmets 我认为您要编写的代码是
for(int i = 0; i < 336000; i++)
int N = 18;
// allocate memory for 18 objects in a continous block
vector<PacketInfo> packets(N);
for(int j = 0; j < N; j++)
// create the packetInfo objects
packets[i] = PacketInfo(i, i);
【讨论】:
所以这只是一个错字...谢谢!顺便说一句,对于向量,这 18 个对象是在堆栈上还是在堆上?如果我没记错的话,如果我希望对象在堆上,它需要是一个指针向量 向量在栈上,PacketInfo 对象在堆上。上面的代码是这样,指针向量可能是也可能不是(因为它取决于你如何初始化指针)。 和你的代码版本完全一样的情况,指针本身在栈上,但它指向的东西在堆上。 好吧,我想我得回去看看内存分配了……再次感谢! 任何时候你在函数中声明一个变量,这个变量就在堆栈上(静态变量是一个例外)。这适用于任何类型的变量,包括指针。与指针的区别在于它们也指向某物,而某物可能不在堆栈上。理解指针的关键是始终将指针和指针指向的内容分开。它们不是一回事。以上是关于动态数组和删除运算符的 boost::python 内存错误的主要内容,如果未能解决你的问题,请参考以下文章
删除由 boost::python 暴露的 std::vector 中的一个指针