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

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

量化橙同学

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值