C++学习——解决一个double free or corruption (!prev)错误
在我的场景下,出现问题的地方是一个for循环,代码如下所示:
for(auto v : _map)
{
value += v.second._value;
}
我咨询了cursor了,它除了一直安利我使用valgrind进行检查,没有给出什么有价值的信息。
debug信息显示,是对v结束遍历,进行析构的时候,出现了double free or corruption (!prev)的问题
首先通过判断map的size和遍历的v的位置,避免了越界访问的可能,然后出现error的位置也不确定,因此我怀疑是内存分配的问题。
还有一个可以佐证的点在于,我平时在使用的时候会同时运行两个程序,一个内存占用比较大,一个内存占用比较小,内存占用比较小的从来没有遇到过这个问题。
通过和chatgpt对话,我知道在linux的场景下,内存分配的默认大小是8M,我在使用进程查询函数发现内存大小果然如此:
ps -ef|grep python #获得进程号
cat /proc/进程号/limits | grep "Max stack size"
这个在我的场景下显然是不太够用的,
因此我才用了两个方法,首先第一个是在cmake里通过设置堆栈大小来解决问题,如下所示:
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-stack_size -Wl,1000000")
另一个就是设置linux的默认栈的空间大小
根据参考文献二的内容:
1.linux查看修改线程默认栈空间大小 ulimit -s
a、通过命令 ulimit -s 查看linux的默认栈空间大小,默认情况下 为10240 即10M
b、通过命令 ulimit -s 设置大小值 临时改变栈空间大小:ulimit -s 102400, 即修改为100M
c、可以在/etc/rc.local 内 加入 ulimit -s 102400 则可以开机就设置栈空间大小
d、在/etc/security/limits.conf 中也可以改变栈空间大小:
#
- soft stack 102400
重新登录,执行ulimit -s 即可看到改为102400 即100M
通过以上的方法,我解决了出现的这个问题
其它的可能导致这个问题的原因(参考文献一,三):
1、多次释放同一内存区,需要检查代码,是否出现了对同以内存区释放两次以上的地方。
2、内存区溢出,malloc申请的内存区大小有限,如果操作不当,要存储的数据大于内存区大小,在free的时候也会检测出来,报这个错误
3.A类包含B类,B类的析构函数中有释放内存的操作,在A类的构造函数中使用了函数体中赋值( b=B() )对B类进行初始化操作,这样就产生了一个实例B(),但是这样就导致了一个严重的问题,生成的B()是临时的,在A的构造函数结束后会销毁B(),释放一次内存。这样当A实例销毁时,会再次调用B的析构函数,导致了二次释放。且原本的属于A类中的实例b的那块内存因为没有进行释放导致内存泄露。
参考文献:
参考文献一:https://blog.csdn.net/alickr/article/details/107976390
参考文献二:http://www.eepw.com.cn/zhuanlan/209347.html
参考文献三: https://blog.51cto.com/u_13977270/3397730