温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

如何分配C语言编程C++动态内存

发布时间:2021-09-28 10:52:00 来源:亿速云 阅读:144 作者:iii 栏目:开发技术

本篇内容主要讲解“如何分配C语言编程C++动态内存”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何分配C语言编程C++动态内存”吧!

目录
  • 动态内存管理

    • 为什么存在动态内存分配

  • 动态内存函数的介绍

    • malloc申请空间和free释放空间

    • 有借有还free释放内存

  • calloc申请内存

    • realloc调整动态内存的大小

      • realloc使用的注意事项

      • 当然realloc也可以直接开辟空间

    • 常见的动态内存错误

      • 1.对NULL指针的解引用操作

      • 2.对动态开辟空间的越界访问

      • 3.对非动态开辟内存使用free释放

      • 4.使用free释放一块动态内存开辟的一部分

      • 5.对同一块动态内存多次释放

      • 6.动态开辟内存忘记释放(内存泄漏)

    • 几个面试题

      • 题目1

      • 题目2

      • 题目3

      • 题目4

    • C/C++程序的内存开辟

      • C/C++程序内存分配的几个区域:

      动态内存管理

      为什么存在动态内存分配

      我们到现在为止掌握的是什么样的内存开辟方式呢

      //创建一个变量
      int val = 20;    //局部变量  在栈空间中开辟4个字节
      int g_val = 10;  //全局变量  在静态区中开辟4个字节
      //创建一个数组
      char arr[10] = {0}; //局部区域 在栈空间中开辟10个字节连续的空间
      char g_arr[5] = {0};//全局区域 在静态区空间中开辟5个字节的连续空间

      如何分配C语言编程C++动态内存

      但是上述的开辟空间的方式有两个特点:

      1.空间开辟大小是固定的。

      2.数组在申明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
      但是对于空间的需求,不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道,那数组的编译时开辟空间的方式就不能满足了。 这时候就只能试试动态内存开辟了。

      c99是支持变长数组的,但现在很多编译器就不支持c99,连vs都不支持,所以就有动态内存的概念

      动态内存函数的介绍

      malloc申请空间和free释放空间

      c语言提供了一个动态内存开辟的函数

      void* malloc(size_t size);

      这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。

      1.如果开辟成功,则返回一个指向开辟好空间的指针。

      如何分配C语言编程C++动态内存

      2.如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。

      如何分配C语言编程C++动态内存

      3.返回值的类型是 void ,所以malloc函数并不知道开辟空间的类型,具体在使用的时候使用者自己来决定。*

      如何分配C语言编程C++动态内存

      4.如果参数 size 为0,malloc的行为是标准未定义的,取决于编译器。

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<errno.h>
      int main()
      {
      	//向内存申请10个整形的空间
      	int* p = (int*)malloc(10 * sizeof(int));
      	if (p == NULL)
      	{
      		//把开辟失败的信息打印出来
      		printf("%s",strerror(errno));
      	}
      	else
      	{
      		//正常使用空间
      		int i = 0;
      		for (i = 0; i < 10; i++)
      		{
      			*(p + i) = i;//在找下标为i的元素
      		}
      		for (i = 0; i < 10; i++)//再把每个元素打印出来
      		{
      			printf("%d ", *(p + i));
      		}
      	}
      	return 0;
      }

      如何分配C语言编程C++动态内存

      那我们可不可以看开辟失败的呢

      我们可以用INT_MAX(他是整形最大),一个超级大的数字

      如何分配C语言编程C++动态内存

      如何分配C语言编程C++动态内存

      如何分配C语言编程C++动态内存

      有借有还free释放内存

      free函数用来释放动态开辟的内存。
      1.如果参数 ptr 指向的空间不是动态开辟的,那free函数的行为是未定义的。
      2.如果参数 ptr 是NULL指针,则函数什么事都不做。

      如何分配C语言编程C++动态内存

      如何分配C语言编程C++动态内存

      注意

      malloc和free是成对使用的,谁开辟谁释放

      calloc申请内存

      在内存中开辟一个数组,把元素都改成零

      函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。

      如何分配C语言编程C++动态内存

      与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0

      如何分配C语言编程C++动态内存

      realloc调整动态内存的大小

      当然我们可以申请空间,但会不会遇到申请的空间不够了,想要增加一些些,大了想要去掉一些些

      如何分配C语言编程C++动态内存

      realloc使用的注意事项

      1.如果p指向的空间之后有足够的内存空间可以追加,则直接追加,后返回p

      2.如果p指向的空间之后没有足够的内存空间可以追加,则realloc函数会重新找一块新的内存区域,开辟一块满足需求的空间,并且把原来的内存中的数据拷贝回来,释放旧的内存空间,最后返回新开辟的内存空间地址

      3.但也有一个大问题,就是开辟INT_MAX,用新的变量ptr来接收realloc返回值

      如何分配C语言编程C++动态内存

      如何分配C语言编程C++动态内存

      当然realloc也可以直接开辟空间

      如何分配C语言编程C++动态内存

      常见的动态内存错误

      1.对NULL指针的解引用操作

      #include<stdio.h>
      #include<stdlib.h>
      int main()
      {
      	int* p = (int*)malloc(40);//没成功就会有大问题
      	int i = 0;
      	for (i = 0; i < 10; i++)
      	{
      		*(p + i) = i;
      	}
      	free(p);
      	p = NULL;
      	return 0;
      }

      如何分配C语言编程C++动态内存

      所以为了防止没有开辟动态内存成功就需要做个判断

      如何分配C语言编程C++动态内存

      2.对动态开辟空间的越界访问

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<errno.h>
      
      int main()
      {
      	int* p = (int*)malloc(5*sizeof(int));
      	if (p == NULL)//这里我的确判断有没有开辟成功了
      	{
      		printf("%s", strerror(errno));
      	}
      	else
      	{
      		int i = 0;
      		for (i = 0; i < 10; i++)//但是我这里访问10个整型的空间
      		{
      			*(p + i) = i;
      		}
      	}	
      	free(p);
      	p = NULL;
      	return 0;
      }

      如何分配C语言编程C++动态内存

      3.对非动态开辟内存使用free释放

      int main()
      {
      	int a = 0;
      	int* p = &a;
      	*p = 20;
      	free(p);
      	p = NULL;
      	return 0;
      }

      如何分配C语言编程C++动态内存

      4.使用free释放一块动态内存开辟的一部分

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<errno.h>
      int main()
      {
      	int* p = (int*)malloc(40);
      	if (p == NULL)
      	{
      		return 0;//如果是空指针就直接返回,不干了
      	}
      	int i = 0;
      	for (i = 0; i < 10; i++)
      	{
      		*p++ = i;//这个++就是bug的地方
      	}
      	//回收空间
      	free(p);
      	p = NULL;
      	return 0;
      }

      如何分配C语言编程C++动态内存

      只要p不是指向申请的空间的首地址,其他地方都是错的

      5.对同一块动态内存多次释放

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<errno.h>
      int main()
      {
      	int* p = (int*)malloc(40);
      	if (p == NULL)
      	{
      		return 0;
      	}
      	//使用
      	//释放
      	free(p);
      	//...
      	free(p);
      	return 0;
      }

      如何分配C语言编程C++动态内存

      6.动态开辟内存忘记释放(内存泄漏)

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<errno.h>
      int main()
      {
      	while (1)
      	{
      		malloc(100);
      	}
      	return 0;
      }

      如何分配C语言编程C++动态内存

      几个面试题

      题目1

      void GetMemory(char* p)
      {
      	p = (char*)malloc(100);
      }
      void Test(void)
      {
      	char* str = NULL;
      	GetMemory(str);
      	strcpy(str,"hello world");
      	printf(str);//这个写法和printf("%s",str);是一样的
      }
      int main()
      {
      	Test();
      	return 0;
      }

      问运行Test函数会有什么样的结果

      如何分配C语言编程C++动态内存

      修改正确

      #include<stdio.h>
      #include<stdlib.h>
      #include<string.h>
      #include<errno.h>
      void GetMemory(char* *p)
      {
      	*p = (char*)malloc(100);
      }
      void Test(void)
      {
      	char* str = NULL;
      	GetMemory(&str);
      	strcpy(str,"hello world");	
      	printf(str);//这个写法和printf("%s",str);是一样的
      	free(str);//用完就释放
      	str = NULL;
      }
      int main()
      {
      	Test();
      	return 0;
      }

      如何分配C语言编程C++动态内存

      题目2

      char* GetMemory(void)
      {
      	char p[] = "hello world";
      	return p;
      }
      void Test(void)
      {
      	char* str = NULL;
      	str = GetMemory();
      	printf(str);
      }
      int main()
      {
      	Test();
      	return 0;
      }

      请问运行Test 函数会有什么样的结果

      输出随机值

      如何分配C语言编程C++动态内存

      如何分配C语言编程C++动态内存

      修改正确

      既然是p被销毁了,那我们让他不销毁就可以了延长它的生命周期用static

      char* GetMemory(void)
      {
      	static char p[] = "hello world";
      	return p;
      }
      void Test(void)
      {
      	char* str = NULL;
      	str = GetMemory();
      	printf(str);
      }
      int main()
      {
      	Test();
      	return 0;
      }

      如何分配C语言编程C++动态内存

      题目3

      void GetMemory(char **p, int num)
      {
      *p = (char *)malloc(num);
      }
      void Test(void)
      {
      char *str = NULL;
      GetMemory(&str, 100);
      strcpy(str, "hello");
      printf(str);
      }

      这题基本和第一题一样,不过这题就只有内存泄漏的错误

      如何分配C语言编程C++动态内存

      修改正确

      #include<stdio.h>
      #include<stdlib.h>
      void GetMemory(char** p, int num)
      {
      	*p = (char*)malloc(num);
      }
      void Test(void)
      {
      	char* str = NULL;
      	GetMemory(&str, 100);
      	strcpy(str, "hello");
      	printf(str);
      	free(str);//用完就释放,防止内存泄漏
      	str = NULL;
      }
      int main()
      {
      	Test();
      	return 0;
      }

      如何分配C语言编程C++动态内存

      题目4

      void Test(void)
      {
      	char* str = (char*)malloc(100);
      	strcpy(str, "hello");
      	free(str);
      	if (str != NULL)
      	{
      		strcpy(str, "world");
      		printf(str);
      	}
      }

      问题非常大的打印出结果

      如何分配C语言编程C++动态内存

      如何分配C语言编程C++动态内存

      修改正确

      #include<stdio.h>
      #include<string.h>
      #include<stdlib.h>
      
      void Test(void)
      {
      	char* str = (char*)malloc(100);
      	strcpy(str, "hello");
      	free(str);//这里考查的是free释放后并没有使str为NULL,所以下面if判断就没有作用,如果使他有作用就让str为NULL
      	str = NULL;
      	if (str != NULL)
      	{
      		strcpy(str, "world");
      		printf(str);
      	}
      }
      int main()
      {
      	Test();
      	return 0;
      }

      这道题真正目的就是让你什么都不打印

      如何分配C语言编程C++动态内存

      C/C++程序的内存开辟

      如何分配C语言编程C++动态内存

      C/C++程序内存分配的几个区域:

      栈区(stack):在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。 栈区主要存放运行函数而分配的局部变量、函数参数、返回数据、返回地址等。

      堆区(heap):一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。分配方式类似于链表。

      数据段(静态区)(static)存放全局变量、静态数据。程序结束后由系统释放。

      代码段:存放函数体(类成员函数和全局函数)的二进制代码。

      到此,相信大家对“如何分配C语言编程C++动态内存”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

      向AI问一下细节

      免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

      c++
      AI