C语言malloc内存,使用越界,free出错的问题!

写在最前:C语言出入门生,遇到点问题,在查找资料和小小钻研后的心得体会,纯属为个人做笔记使用!若有大神光顾,不足之处还望不吝指正。若有严重错误,请建议我删除!

在学习C语言的时候,写了这样一段代码:

#define  _CRT_SECURE_NO_WARNINGS
#include "stdlib.h"
#include "stdio.h"
#include "string.h"

int fun(char **mystr_one, int *strone_len)
{
	int fun_state = 0;
	char *tem = NULL;
	tem = (char*)malloc(8);
	strcpy(tem, "qwertyui");
	*mystr_one = tem;
	*strone_len = strlen(tem);
	tem = NULL;

	return fun_state;
}
void main()
{

	int main_stat = 0;
	char *str_one = NULL;
	int strone_len = 0;

	main_stat = fun(&str_one, &strone_len);
	if (main_stat != 0)
	{
		printf("fun error:%d", main_stat);
	}
	printf("str_one is :%s\n", str_one);

	if (str_one != NULL)
	{
		free(str_one);
		str_one = NULL;
	}

	printf("\n");
	system("pause");

}

由于初学者,忘了字符串结尾还要追加一个结束字'\0',所以申请内存是存在问题的,标红的那一句,在使用这块内存的时候,其实使用了9个字节,但是只申请了8个字节,但是使用的时候却没有报错,free时候却发现程序意外停止。尝试了很多次之后,终于将问题定位,就是申请内存不当造成。原因如下:

①:有没有人考虑过free()函数为什么不需要指定内存大小就能对动态申请的内存块执行释放操作?这其实就暗含着问题的来源,事实上,malloc在动态申请内存的时候并不是仅仅截取了用户指定大小的一块内存给用户使用,在申请得到的这块内存的前后若干字节里都存着有关这块内存的信息,其中做主要的就是这块内存的大小,在free时候,函数自动查找这个数值进行释放。实测,若malloc返回得到的是int型的内存块时,这块内存的大小的数值存在距离内存块头指针前面0x10的一个int型内存块中,(即,若内存块头指针是0x001c50,申请了10个字节,那么在0x001c40开始的4个字节里的数值刚好是0x28(16进制数))。

②:有了①中的问题的研究,原因就可想而知了,既然前面有信心,那后面也一定有相关信息,一旦内存越界,会造成该内存块相关信息遭到破坏,导致free出错。

所以申请内存一定要计算好使用量,即使多申请也不能少申请,当然多申请是可以避免此类问题但是会造成内存浪费,也不是好办法,最好的就是计算好使用量。

关于问①中的实验,已经有大神做过了,参考链接:

https://www.cnblogs.com/xxNote/p/4009359.html

https://blog.csdn.net/fovwin/article/details/8272717

猜你喜欢

转载自blog.csdn.net/qq_24631105/article/details/80676019