首页 > 技术文章 > HEAP CORRUPTION DETECTED:after Normal block错误方法解决,C++动态内存分配知识点

zeroonegame 2020-10-17 22:12 原文

今天使用VS2019编写程序,采用动态内存分配,但是在释放内存时出现问题。

在这里插入图片描述

程序使用了动态内存分配,因此需要程序员手动释放空间。

然而释放过程出现问题。 设置断点调试后,发现报错语句在这三行

在这里插入图片描述

原始代码如下,该程序的作用是从串s中删除所有和串t相同的子串。
程序本身效率高低不在本篇博客讨论范围,详情自行百度。

#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int* brute_force(const string& s,const string& t)
	{
		int* pos = new int[ s.length() / t.length() ];
		int i, j, n=1, s_len = s.length(), t_len = t.length();
		bool flag;
		pos[0] = 0;
		for (i = 0; i < s_len; ++i) {

			flag = true;
			for ( j = 0; j < t_len; ++j)
			{
				if (s[i+j]!=t[j])
				{
					flag = false;
					break;
				}
			}

			if (flag==true)
			{
				++pos[0];
				pos[n] = i;
				++n;
			}

		}
		return pos;
	}

void problem413_Brute_Force()
	{
		string s, t;
		cout << "input s :" << endl;
		cin >> s;
		cout << "input t :" << endl;
		cin >> t;

		int* pos = brute_force(s,t);
		char* sub_s = new char[s.length() - pos[0] * t.length() ];
		int j=0, s_len = s.length(), t_len = t.length();
		int* at_subs = new int[s_len];

		for (int i = 0; i < s_len; ++i) {
			at_subs[i] = 1;
		}

		for (int i = 1; i <= pos[0]; ++i)
		{
			for (j = pos[i]; j < pos[i] + t_len; ++j) {
				at_subs[j] = 0;
			}
		}
		
		int n = 0;
		for (int i = 0; i < s_len; ++i)
		{
			if (at_subs[i] == 1) sub_s[n++] = s[i];
		}
		sub_s[n] = '\0';
		
		cout << sub_s << endl;

		delete sub_s;
		delete pos;
		delete at_subs;
		return;
	}

int main()
{
	problem413_Brute_Force();
}

本博客主要解决上述堆内存报错时的分析。

首先使用暴力算法求出s中每一个包含t的位置,之后返回包含信息的数组pos。
pos[0]代表总共重复的次数,其余的pos[i]代表第i次重复时,s中出现的t串在s中的位置。

比如,s=“acdacdacdb” t=“acd”
那么,pos[0]=3 , pos[1]=0 , pos[2]=3 , pos[3]=4

其中,pos为动态申请所得。
同样的,subs,at_subs均由动态内存分配得来。

分析后发现,这一句会分配的空间不足以支持后面的操作,即后面出现的越界访问的情况。因为修改了申请的内存以外的内存,从而导致释放指针指向的堆内存出现错误。

也就是说,pos[0]=3 , pos[1]=0 , pos[2]=3 , pos[3]=4 这些信息需要4个int的空间存储,但是只分配了 int(10/3) = 3个空间,因此会出现内存访问越界的情况。

在这里插入图片描述
同时,这一语句也可能因为s串和t串没有重复的,
在这里插入图片描述
,而在后面这句中报错,(越界访问,因为 n 的值已经超过了sub_s的分配得到的最大长度

在这里插入图片描述

修改的方法,将上述两句改为如下即可,即适当多分配一些空间,以免内存访问越界:
在这里插入图片描述
在这里插入图片描述

总结:

动态内存分配坑很深,出现博客开始时的问题时,应当仔细检查是否出现了对于动态申请的内存空间越界访问的情况,因为在程序执行过程中,越界访问并没有报错(至少在博主使用过程时,对于动态内存分配的空间越界访问未报错),修改程序逻辑,避免出现越界访问的情况,否则无法正常释放动态分配的内存空间

推荐阅读