初夏小谈:内存管理之常见内存错误(重点干货)

想来说说内存管理已经好长时间了,但是不知如何较好的表达。整理了几天,来给大家分享这种底层问题。

学好C语言就要学好内存管理。那么内存分为那几个区呢?

先来说说内存中大致的这几个区:栈区,堆区,全局变量区,和代码区。

栈区:就是用来保存局部变量。栈上的内容只在函数的范围内存在,当函数运行完毕后,这些内容就被自动销毁。

          优点:效率高

          缺点:空间大小有限,比如内存是8G的话栈所拥有的空间仅仅在1M到几M之间,不同机器可能有所差别,但栈着实内存很小。

堆区:就是由malloc系列函数或new操作符分配的内存。其生命周期由free或delete决定,在没有释放之前一直存在,直到程序结束。

          优点:使用灵活。空间相当大,一个8G内存,堆一般占据了7G多。

          缺点:容易出错。比如没有及时free会导致内存泄漏,不要以为分配的那么一点点内存无所谓,这在几天或者长达几个月的不停息的服务器程序上跑,将会异常危险。

全局区:就是存放全局变量和静态变量的区域。当然常量字符串也保存在此。全局变量区的内容在整个程序的生命周期内都存在,它由编译器在编译的时候分配。

代码区:就是存放代码的区域

扫描二维码关注公众号,回复: 4231158 查看本文章

接下来说说内存错误的几种问题

第一种:定义了指针变量,却没有为指针分配内存,就是指针没有指向一块合法的内存。

来看看这个例子:

​
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void Test1()
{
	typedef struct stu
	{
		char* name;
		int score;
	}stu;
	stu student, *ptr;

	strcpy(student.name, "Jack");
	student.score = 90;
}

int main()
{
	Test1();
	system("pause");
	return 0;
}

​

在定义结构体指针ptr时只为它分配了4个字节,指针name指向了一个非法的地址。指针内部存储着可能是一些乱码,拷贝这个字符串的话,就是把字符串往乱码所指向的内存上拷贝。这块内存name指针根本无权访问。办法就是为name分配一块内存。

那么改成这样呢?

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

void Test1_1()
{
	typedef struct stu
	{
		char* name;
		int score;
	}stu;
	stu student, *ptr;

	ptr = (stu*)malloc(sizeof(stu));//为结构体分配一块内存空间
	strcpy(ptr->name, "Jack");
	student.score = 90;
	printf(ptr->name);
	free(ptr);
	ptr = NULL;
}

int main()
{
	Test1_1();
	system("pause");
	return 0;
}

小可爱们是不是可以了呢?很抱歉它还是有问题,其关键在于它还是没有为name指针指向分配一块内存。不要被malloc蒙蔽了眼睛。她的确是为结构体分配一块空间,但并没有为结构体成员指针分配空间。那么应该怎么做呢?看看下面代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>

//解决上述问题
void Test1_2()
{
	typedef struct stu
	{
		char* name;
		int score;
	}stu;
	stu *ptr;

	ptr = (stu*)malloc(sizeof(stu));//为结构体分配一块内存空间
	ptr->name = (char*)malloc(sizeof(stu));//为结构体指针name分配一块内存空间
	strcpy(ptr->name, "Jack");
	printf(ptr->name);

	free(ptr);
}

int main()
{
	Test1_2();
	system("pause");
	return 0;
}

OK,为结构体成员name指针分配了一块内存终于可以,存放“Jack”了哈哈,细心地小可爱发现没有,我没有释放那块内存空间,这就存在问题,内存泄漏。好了再free前面再加一个并且置空,第二个free也要置空就OK了,粗心的小伙伴注意了。想要源码的伙伴们请搜索

https://github.com/AventadorSQ/zhen_yuanma/commit/b1a3b4caccbb71801cf4ed9022b6d4fce7c34d90

                                                                                                                                                          珍&源码

猜你喜欢

转载自blog.csdn.net/IT_xiaoQ/article/details/84492302