热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

c/c++开发分享Linux(C/C++)动态内存分配malloc以及相关学习

1、cc++内存分类(引用c++primer)(对象在c语言中可以理解为变量)1.1、静态内存:静态内存用来保存局部static对象、类static数据成员、以及定义在

1、c/c++内存分类(引用c++ primer )(对象在c语言中可以理解为变量)

1.1、静态内存:静态内存用来保存局部static对象、类static%ignore_a_1%成员、以及定义在任何函数之外的变量

1.2、栈内存:栈内存用来保存定义在函数内非static对象。(当然包含函数参数开辟的内存)

1.3、动态内存:每个程序还有一个内存池,这部分内存被称作自由空间(free store)或者堆(heap)。程序用堆来存储动态分配的内存(dynamically allocate)的对象,也就是,那些在程序运行时分配的对象。动态对象的生存期由程序来控制,所以,不再使用动态对象时,我们的代码必须显示的销毁它们。

note:分配在静态或栈内存的对象由编译器自动创建和销毁,对于栈对象,仅在其定义的程序块运行时才存在,static对象在使用之前分配,在程序结束时销毁。

2、c/c++内存分配相关函数以及运算符

2.1、c分配内存函数如下:(在linux下查询得知,使用命令:man 3 malloc )

    
  name         malloc, free, calloc, realloc - allocate and free dynamic memory  synopsis         #include            void *malloc(size_t size);            void  free(void *ptr);         void *calloc(size_t nmemb, size_t size);         void *realloc(void *ptr, size_t size);  

 

size_t类型: size_tis the unsigned integer type of the result of

size_tcan store the maximum size of a theoretically possible object of any type (including array).

size_tis commonly used for array indexing and loop counting. programs that use other types

它是一个与机器相关的unsigned类型,其大小足以保证存储内存中对象的大小(来源百度百科)

malloc函数分配size个字节,分配成功返回指向这块分块内存的指针。分配失败将返回null;

calloc跟malloc类似,不同点是calloc分配了nmemb*size个字节。

realloc:重新分配内存,一般用于程序追加内存。将改变ptr指向的内存块字节为size,如果一开始ptr为null,

那么这个函数实现类似malloc,否则ptr指向的内容在范围(ptr起点和终点(min(old size,new size))将不会改变,如

果new size 大于old size(ptr之前分配的字节),那么多出的那部分是没有初始化的,所以我要习惯初始化这部分内

存。其它部分也类似malloc。

free:这个函数将释放由malloc、calloc、realloc返回指向的内存指针ptr,否则free(ptr)将是未定义的行为。如果

ptr为空,那么free(ptr),将什么都不做。这告诉我们,free(ptr)之后,请务必ptr=null; 若不然,ptr便成了悬空指

针,如果往后没分配内存给ptr又再free(ptr),这时将产生未知的错误。

note:通常使用malloc跟free,因为另外两个函数,一般情况下,其实malloc可取代他们。
举个例子,程序如下(大概流程):

 

  // code...   char *ptr = null;   ptr = (char *)malloc(100 * sizeof(char));   if (null == ptr)   {            打印strerror(errno);  //在linux打印出错信息  }   gets(ptr);     // code...   free(ptr);   ptr = null;   //好习惯  // code...   

 

2.2c++分配内存

在c++中,动态内存的管理是通过一堆运算符来完成的.

new: 在动态内存中为对象分配空间并返回一个指向该对象的指针。
delete: 接受一个动态对象的指针,销毁一个对象,并且释放与之关联的内存。(数组:delete []数组名),

note:c跟c++分配内存不要混合使用,比如使用new分配的内存,使用free()释放,要知道delete需要完成系列的析构操作,而free只是简单释放而已。有时候侥幸通过,不能保证别的编译器就能通过。

3、分配内存引起注意的地方(大概)

3.1、申请了内存空间后,必须检查是否分配成功。
3.2、当不需要再使用申请的内存时,记得释放;释放后应该把指向这块内存的指针指向null,防止程序后面不小心使用了它。
3.2、这两个函数(malloc、free)应该是配对。如果申请后不释放就是内存泄露;如果无故释放那就是什么也没有做。释放只能一次,如果释放两次及两次以上 会出现错误(释放空指针例外,释放空指针其实也等于啥也没做,所以释放空指针释放多少次都没有问题)。
3.4、虽然malloc()函数的类型是(void *),任何类型的指针都可以转换成(void *),但是最好还是在前面进行强制类型转换,因为这样可以躲过一些编译器的检查。
3.5、c使用自定义函数分配内存一般使用二级指针。

来看一个例子,自定义函数分配内存。

 

  #include  #include    char *allocate_p(char * str)  {  	str=(char *)malloc(sizeof(char));  }  int main(void )  {  	char *p;//为了测试不初始化null      allocate_p(p);      free(p);      printf("ok");  	return 0;  }  /*   * 使用gcc编译通过,运行报错  *** glibc detected ***   *** ./test1: free(): invalid pointer: 0xb771bff4 ***  *** 说明p是一个悬空的指针,那么allocate_p()没分配空间。  *** 这非常类似值传递,将p没初始化的内存传递给str,函数给str分配内存,  *** 这时p还是原来的那个没初始化内存。当分配函数完了之后,str的动态分配的内存还没释放,  *** p依旧什么都不是。这就导致,该释放的没释放,不该释放的释放了  *** free(p)是未定义的错误  */  

 

解决方案。

  /*   * 我们是用指针传递来解决值传递不足。   * 这时候我们也可以利用类似想法来解决这个问题。   * */  #include  #include    char *allocate_p(char ** str)  {  	*str=(char *)malloc(sizeof(char));  }  int main(void )  {  	char *p;//为了测试不初始化null      allocate_p(&p);      free(p);      printf("ok");  	return 0;  }  /*   * allocate_p(&p);str=p的地址。   * 那么*str=p。因此   * *str=(char *)malloc(sizeof(char));   * 等价于  p==(char *)malloc(sizeof(char));   * 当free(p) 相当于free(str),注意就不会内存泄漏了  */  

再来看一个经典的例子。

 

  #include   char *returnstr()  {      char *p="hello world!";      return p;  }  int main()  {      char *str;       str=returnstr();      printf("%s/n", str);            return 0;  }  #include   char *returnstr()  {      char p[]="hello world!";      return p;  }  int main()  {      char *str;       str=returnstr();      printf("%s/n", str);            return 0;  }  /*  分析:这两个函数唯一差别是returnstr中局部变量*p/p[],  "hello world"作为静态字符串实际上存储在数据区,但写程序的人不知道这个地址,而程序本身知道。  当某一函数以{ char p[] = "hello world"; ...}方式使用此静态字符串时,实际上相当于:    char p[12];    strcpy(p, "hello world");    ....  p[12]是在栈里临时分配的。虽然p指向的内容是"hello world", 但是这是复制品,不是原件。  当函数结束,char p[]就被程序回收了,所以p[]的内容就不再是"hello world"了。  但如果以char *p="hello world"的方式使用,p指向的是静态字符串存储的位置,  也就是说指向"hello world"的原件,当然没有问题了。  如果想坚持用char p[]而不使用char *p, 有效方法必须是:  char *returnstr()  {  static char p[]="hello world";  return p;  }  static char []是静态的,存储在数据区。  */						

 


推荐阅读
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • malloc 是 C 语言中的一个标准库函数,全称为 memory allocation,即动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过 malloc 动态分配内存。 ... [详细]
  • 本文总结了Java初学者需要掌握的六大核心知识点,帮助你更好地理解和应用Java编程。无论你是刚刚入门还是希望巩固基础,这些知识点都是必不可少的。 ... [详细]
  • 本文详细介绍了 PHP 中对象的生命周期、内存管理和魔术方法的使用,包括对象的自动销毁、析构函数的作用以及各种魔术方法的具体应用场景。 ... [详细]
  • 题目链接: L - Floating-Point Numbers。题目要求处理带有15位小数的浮点数,计算其二进制表示的最大位数。 ... [详细]
  • iOS 不定参数 详解 ... [详细]
  • 【妙】bug称它为数组越界的妙用
    1、聊一聊首先跟大家推荐一首非常温柔的歌曲,跑步的常听。本文主要把自己对C语言中柔性数组、零数组等等的理解分享给大家,并聊聊如何构建一种统一化的学习思想 ... [详细]
  • C语言中全部可用的数学函数有哪些?2.longlabs(longn);求长整型数的绝对值。3.doublefabs(doublex);求实数的绝对值。4.doublefloor(d ... [详细]
  • 本文介绍了在 Java 编程中遇到的一个常见错误:对象无法转换为 long 类型,并提供了详细的解决方案。 ... [详细]
  • Halcon之图像梯度、图像边缘、USM锐化
    图像梯度、图像边缘、USM锐化图像梯度、图像边缘、USM锐化图像梯度、图像边缘、USM锐化图像卷积:1.模糊2.梯度3.边缘4.锐化1.视频教程:B站、 ... [详细]
  • 单片微机原理P3:80C51外部拓展系统
      外部拓展其实是个相对来说很好玩的章节,可以真正开始用单片机写程序了,比较重要的是外部存储器拓展,81C55拓展,矩阵键盘,动态显示,DAC和ADC。0.IO接口电路概念与存 ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • 开机自启动的几种方式
    0x01快速自启动目录快速启动目录自启动方式源于Windows中的一个目录,这个目录一般叫启动或者Startup。位于该目录下的PE文件会在开机后进行自启动 ... [详细]
  • 本文对常见的字符串哈希函数进行了全面分析,涵盖了BKDRHash、APHash、DJBHash、JSHash、RSHash、SDBMHash、PJWHash和ELFHash等多种算法。这些哈希函数在不同的应用场景中表现出各异的性能特点,通过对比其算法原理、计算效率和碰撞概率,为实际应用提供了有价值的参考。 ... [详细]
  • 在腾讯云服务器上部署Nginx的详细指南中,首先需要确保安装必要的依赖包。如果这些依赖包已安装,可直接跳过此步骤。具体命令包括 `yum -y install gcc gcc-c++ wget net-tools pcre-devel zlib-devel`。接下来,本文将详细介绍如何下载、编译和配置Nginx,以确保其在腾讯云服务器上顺利运行。此外,还将提供一些优化建议,帮助用户提升Nginx的性能和安全性。 ... [详细]
author-avatar
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有