C++类对象构造函数出错malloc: memory corruption

博客内容涉及C++编程中遇到的两个问题:一是执行`sudomakeinstall`时找不到-lclass_loader库,通过修改系统时间解决;二是DA代码中线程启动PM的run函数时出现内存错误,经过gdb和valgrind调试,发现是由于内存结构破坏和字节对齐问题导致。最终通过调整代码和使用`pragma pack`修复了问题。

问题1

问题概述:

编译插件代码,cmakemake均成功,但是执行sudo make install时报错cannot find -lclass_loader,在CMakeLists.txt中添加find_package(class_loader)cmake时提示可以找到class_loader,但是make install 还是报错。

解决方案:

修改系统时间 sudo date -s “YYYY/MM/DD HH:mm:ss”

问题2

问题概述:

pm_test中起线程执行pmrun函数,单独运行device_manager_test/test_pm/test_show成功,但是在DA代码中以同样的方式起线程执行pm中的run函数时报内存错误。

 场景pm_test代码:

DApm部分代码

 

运行DA代码报错:

 

 由于前后都是出错位置前后都是场景相关的打印,所有被认定时我们的问题。

对比代码后排除DA错误调用pm的可能性。

通过gdb调试定位到是在起线程pm中的run重载函数时出错的,不起线程进入run函数在new物理域的对象时程序也会异常结束,因此猜想在起线程之前内存结构已经遭到了破坏。后又通过valgrind调试提示在构造函数中调用新增的mapempty()函数出现异常:Invalid write of size 8Invalid read of size 8,之前遇到过同样的问题,是由于新增的int类型变量在两个map变量之后声明,在构造函数中给该int类型变量赋初值时也出现异常,后将该变量定义移动到新增的两个map变量之前声明就没再出现过异常现象,但是并没有解决根本问题。

将构造函数中对新增的两个map变量的判空和清空处理的操作都删除了之后调试发现没有Invalid read of size 8了,但是还有Invalid write of size 8

由于新增的map变量中含有嵌套mapvoid *,猜想可能是由于void *map没有初始化导致的,因此重新编译了两个版本对新增的两个map变量进行了初始化,还是存在内存错误。

map变量初始化:

方案1

 

方案2

构造函数初始化列表

PluginManager:: PluginManager():paramsFlag(), _runMap()

{

  …..

}

通过gdb反复调试,进入run函数中将入参中map通过“=”赋值给新增map变量_runMap时程序异常退出,由于_runMap中含有嵌套mapvoid *,猜测是map浅拷贝造成的,但是通过测试并没有出现异常。

最终解决方案:

1. 参考 C语言 GCC编译的程序运行报错 malloc.c:2401: sysmalloc: Assertion 的分析解决_星空千代-优快云博客

   修改方案:

2. 参考 【已解决】C++中由于字节对齐引起的踩内存问题_WINGREZ‘S BLOG-优快云博客

  修改方案:

  pluginManager.h中类的声明前后分别增加#pragma pack(push, 4)#pragma pack(pop)

经验证,两种方式均可解决问题。

 

`malloc(): memory corruption` 报错通常意味着在使用动态内存分配函数 `malloc` 及其相关操作,程序对堆内存的管理出现了问题,导致堆内存数据结构被破坏。以下是一些可能的原因及分析: #### 1. 缓冲区溢出 在使用 `malloc` 分配内存后,如果向分配的内存区域写入的数据超过了分配的大小,就会覆盖相邻的堆内存区域,破坏堆的内部数据结构。例如: ```c #include <stdio.h> #include <stdlib.h> int main() { char *ptr = (char *)malloc(10); for (int i = 0; i < 20; i++) { ptr[i] = 'A'; } free(ptr); return 0; } ``` 在这个例子中,`malloc` 只分配了 10 个字节的内存,但程序试图写入 20 个字符,这会导致缓冲区溢出,可能触发 `malloc()` 内存损坏错误。 #### 2. 重复释放内存 对同一块已经释放的内存再次调用 `free` 函数,会破坏堆的管理结构。例如: ```c #include <stdio.h> #include <stdlib.h> int main() { char *ptr = (char *)malloc(10); free(ptr); free(ptr); // 重复释放内存 return 0; } ``` #### 3. 释放非 `malloc` 分配的内存 如果尝试释放不是通过 `malloc`、`calloc` 或 `realloc` 分配的内存,也会导致堆损坏。例如: ```c #include <stdio.h> #include <stdlib.h> int main() { char arr[10]; free(arr); // 释放非动态分配的内存 return 0; } ``` #### 4. 内存操作函数使用不当 在使用 `memcpy`、`strcpy` 等内存操作函数,如果参数设置不正确,可能会导致内存越界访问。例如,`memcpy` 的 `size` 参数比分配的空间大: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char *ptr = (char *)malloc(10); char source[20] = "This is a long string"; memcpy(ptr, source, 20); // size 参数过大 free(ptr); return 0; } ``` ### 解决建议 - **检查内存分配和释放**:确保每次 `malloc` 都有对应的 `free`,且不会重复释放内存。 - **检查缓冲区边界**:在向分配的内存写入数据,确保不超过分配的大小。 - **使用调试工具**:可以使用 `valgrind` 等工具来检测内存泄漏和内存损坏问题。例如: ```bash valgrind --leak-check=full ./your_program ``` ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值