指针的动态初始化malloc与销毁free

2023-05-16

指针动态初始化:

int *p = (int*)malloc(sizeof(int)*3);//初始化为指向3个元素的数组
if(!p) exit -1;//这个地方一定要进行判断,因为若动态初始化不成功,在使用p[0]、p[1]、p[2]时报错。
指针的销毁:

free(p);
p = NULL;//避免p为野指针,需要赋值为NULL
         //p中的值仍为原先的内存地址,此时要进行赋值NULL。
         //释放内存后,赋值为NULL的好处还有:当p为NULL时,即便再free n次也不会出错!!!
注意:free的含义:free之后,是将由malloc分配的内存交还给系统支配,而代码支配不了了,即由malloc分配的内存中内容由系统进行处理。

其中存在两个值:一个是指针的值,指针的值并未发生改变,还是原先指向malloc分配的地址。

另一个是malloc分配的内存值,这其中的值取决于系统有没有使用该内存,如果使用了,该内存中的值会发生改变,如果没有使用,则还是保持原先的值。

总结:
初始化要判断内存是否申请成功;
销毁时要赋值NULL 。
//************************

1、变量内存的动态分配(创建)与释放:通过指针,动态间接赋值、取值

指针变量名=new 数据类型(初始值); 初始值可省略,后边再赋值。

delete 指针变量名;

复制代码


#include<iostream>
using namespace std;
int main() {
    //int *p = new int; *p = 5;
    int *p = new int(5);//new运算符,动态创建一个int型变量(无变量名),值为5。
    cout << *p;//输出所指地址的值
    delete p;//释放指针变量的内存空间
    return 0;
}  

复制代码

2、一维数组的动态分配(创建)与释放:

指针变量名=new 数据类型[正整数常量、变量或表达式];

delete [ ]指针变量名;

复制代码


#include<iostream>
using namespace std;
int main() {
    int *p = new int[5];//new运算符,动态创建一个int型数组(无数组名)。
    *(p + 1) = 10;//赋值第2个元素
    //或p[1]=10;
    cout << p[1];//输出所指地址的值
    delete []p;//释放指针变量数组的内存空间
    return 0;
}  

复制代码

显示Fibonacci数列的前N项,0,1,1,2,3,5,8,…

复制代码


#include<iostream>
using namespace std;
int main() {
    int N;
    cin >> N;

    int *p = new int[N]; //动态创建包含N个元素的数组
    p[0] = 0; p[1] = 1;//给定第1、2元素的值,等效*p=0;*(p+1)=1;
    for (int i = 2; i < N; i++){
        p[i] = p[i - 1] + p[i - 2];
    }
    for (int i = 0; i < N; i++)
    {
        cout << p[i] << " ";
    }
    delete []p;//释放指针变量数组的内存空间
    return 0;
}  

复制代码

//************************

什么是动态内存的申请和释放?
 
当程序运行到需要一个动态变量时,需要向系统的堆中申请一块内存,用来存储这块变量,这就是内存的申请。当程序不需要这个变量时,就需要把申请的这块内存释放掉,这就是内存的释放。往往内存的申请和释放是一起使用的,只要有内存的申请,就要有内存的释放,避免出现内存泄漏。
 
C语言指针的申请:
 
(1).在C语言中使用malloc函数申请内存,函数原形:  void* malloc(size_t size);
参数size代表申请的内存的字节数,参数size_t代表指针的类型,比如int char或者是结构体的类型。如果内 存申请成功返回内存的首地址,如果申请失败,返回NULL(注意NULL全部大写)
 
(2).在使用该函数的过程中,需要注意以下几点:
 
1.该函数的参数很简单,只是申请内存的大小,单位是字节
2.申请内存后,必须要检查是否内存分配成功。
3.申请到的内存是一块连续的内存,该函数和free()函数配对使用。
4.虽然该函数的类型是(void*),但是在使用时还是建议进行强制类型转换
  
(3).内存申请的例子:
 
char *P = NULL;(给指针初始化,防止出现野指针)
 
P = (char *)malloc(10 * sizeof(char));  
 
if(P == NULL){
exit(1);
}else{
gets(P);
}
 
 
C语言指针的释放:
 
(1).在C语言中使用free函数释放内存,函数原形: void free(void *ptr);
 
参数ptr代表内存的首地址,该函数没有返回值。
 
(2).在使用该函数的过程中,需要注意以下几点:
1.该函数释放的是指针指向的内存,释放的是内存,不是指针。释放内存后指针要指向NULL
2.和malloc函数配对使用,内存申请后要记得释放,避免内存泄漏。
3.不允许重复释放。
 
(3).内存释放的例子:
 
if(P != NULL){
free(P);
P = NULL; //指针释放之后并不为空,要设置其为空。
}
 
 
注意:
 
1.free()函数只能释放堆空间,堆是大家共有的空间,分局部堆和全局堆,全局堆是没有分配的空间,局部堆是用户分配的空间。用过堆的内存之后要记得还给系统,不然容易发生内存泄漏。
 
2.栈是线程独有的,每个线程的栈都是互相独立的,每个函数都有自己的栈,栈被用来在函数之间传递参数。像代码区,静态变量,全局变量,栈区上的变量都是不需要程序员进行释放的。(这些区域上的空间,不能用free()函数释放)
 
3.野指针:野指针指的是指向“垃圾”内存的指针,不是NULL指针。出现野指针主要有以下几个原因:
      ①.指针没有初始化(指针如果没有初始化,值是不确定的。也就是说,没有初始化的指针,指向的是垃圾内存,非常危险。)
      ②.指针free之后,没有设置为NULL。
      ③.指针超越了变量的作用范围。指针操作时由于逻辑上的疏忽,导致指针访问了非法内存,这种情况是非常容易出现的。
      ④.不要返回指向栈内存的指针。
//***************************

主要初步介绍malloc、free、calloc、realloc的基本。日后会有更详细的内容。

malloc、free分别用于动态内存分配和释放。

malloc会从内存池里提取一块合适的内存(连续的),并返回指向这块内存(起始位置的指针,该指针的类型为void*指针(因为malloc不知道你请求的内存需要存储的数据类型),而且这块内存并没有初始化。

如果操作系统无法提供给malloc足够的内存,malloc就会返回一个NULL指针。因此必须对每个从malloc返回的指针进行检查。

复制代码

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 
 4 int main() 
 5 {
 6     int *pi;
 7     int i;
 8     pi = malloc(25 * sizeof( int ));
 9     
10     if( pi == NULL )
11     {
12     printf( "Out of memory!\n" );
13     exit(1);
14     }
15     
16     for(i = 0; i != 25; i++)
17         pi[i] = i;
18 
19     for(i = 0; i != 25; i++)
20         printf("%d ", pi[i]);
21     printf("\n");
22 
23     return 0;

复制代码

24 } 

 

calloc也可以用于内存分配,但是返回指向内存的指针之前会初始化为0。而且calloc和malloc请求内存数量的方式也不一样。

realloc用于修改一个原先已经分配的内存大小。PS:若原来的内存块无法改变大小,realloc将分配另一块正确的小的内存,并把原来的那块内存的内容复制到新的内存块。

free函数的参数为一个先前从malloc、calloc、realloc返回的值。对NULL指针不会产生任何效果。

 

动态内存分配最常见的错误是忘记检查请求的内存是否分配成功。

《C与指针》里面提供了一个程序可以减少错误的内存分配器。

代码如下:

1 #include <stdlib.h>

3 #define malloc  //用于防止由于其他代码块直接塞入程序而导致偶尔直接调用malloc
4 #define MALLOC(num, type) (type *)alloc((num) * sizeof(type))//接受元素的数目和类型,调用alloc函数获得内存,alloc调用malloc并进行检查,确保返回的指针不是NULL

5 extern void *alloc( size_t size ); 

复制代码

 1 #include <stdio.h>
 2 #include "alloc.h"
 3 #undef malloc
 4 
 5 void *alloc( size_t size )
 6 {
 7     void *new_mem;
 8     /*
 9      * 请求所需的内存,并检查是否分配成功
10      */
11     new_mem = malloc( size );
12     if( new_mem == NULL )
13     {
14         printf("Out of memory!\n" );
15         exit(1);
16     }
17     return new_mem;

复制代码

18 } 

  1 #include <stdio.h>

复制代码

 2 #include "alloc.h"
 3 
 4 int main()
 5 {
 6     int *new_memory;
 7     int i;
 8 
 9     /*
10      * 获得一个整型数组
11      */
12     new_memory = MALLOC( 25, int );
13     
14     for(i = 0; i != 25; i++)
15         new_memory[i] = i;
16 
17     for(i = 0; i != 25; i++)
18         printf("%d ", new_memory[i]);
19     printf("\n");
20     return 0;
21 }

复制代码

//***************************

关于malloc申请内存的函数


一、定义
malloc函数是一种分配长度为num_bytes字节的内存块的函数,可以向系统申请分配指定size个字节的内存空间。malloc的全称是memory allocation,中文叫动态内存分配,
函数返回的类型是void*类型。void*表示未确定的类型。

C,C++规定,void* 类型可以通过类型转换强制转换为任何其它类型的指针。


二、函数声明与使用


头文件
#include <stdlib.h>
或者
#include <malloc.h>


void *malloc(size_t size);


备注:void* 表示未确定类型的指针,void *可以指向任何类型的数据,更明确的说是指申请内存空间时还不知道用户是用这段空间来存储什么类型的数据(比如是char还是int或者其他数据类型)。


三、与new的区别


1)从本质上来说,malloc(Linux上具体实现可以参考man malloc,glibc通过brk()&mmap()实现)是libc里面实现的一个函数,如果在source code中没有直接或者间接include过stdlib.h,那么gcc就会报出error:‘malloc’ was not declared in this scope。如果生成了目标文件(假定动态链接malloc),如果运行平台上没有libc(Linux平台,手动指定LD_LIBRARY_PATH到一个空目录即可),或者libc中没有malloc函数,那么会在运行时(Run-time)出错。new则不然,是c++的关键字,它本身不是函数。new不依赖于头文件,c++编译器就可以把new编译成目标代码(g++4.6.3会向目标中插入_Znwm这个函数,另外,编译器还会根据参数的类型,插入相应的构造函数)。


2)在使用上来说
   
   1、new 返回指定类型的指针,并且可以自动计算所需要大小 

int *p;
p = new int;//返回类型为int *类型(整数型指针),分配大小为sizeof(int);
   


而 malloc 则必须要由我们计算字节数,并且在返回后强行转换为实际类型的指针。


int *p;
p = (int*)malloc(sizeof(int) * 128);//分配128个(可根据实际需要替换该数值)整型存储单元,//并将这128个连续的整型存储单元的首地址存储到指针变量p中
double *pd = (double*)malloc(sizeof(double) * 12);//分配12个double型存储单元,//并将首地址存储到指针变量pd中


  2、另外有一点不能直接看出的区别是,malloc 只管分配内存,并不能对所得的内存进行初始化,所以得到的一片新内存中,其值将是随机的。所以malloc的内存要首先进行初始化
 

 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

指针的动态初始化malloc与销毁free 的相关文章

  • 在 C 中 Malloc 一个二维数组[重复]

    这个问题在这里已经有答案了 每次我首先为二维数组分配内存时 我都会创建一个数组int 然后使用 for 为每个元素分配内存 例如 int arr malloc N sizeof int for i 0 i lt N i arr i mall
  • alloca 函数崩溃,但 malloc 正常

    请解释一下崩溃的原因 我的第 3 方代码意外崩溃并出现 EXC BAD ACCESS static int overwrite selector struct srm target srm MARFileRemoverProgressBlo
  • C malloc valgrind 大小写入无效

    我曾经遇到过公平份额 malloc 无效写入 以及本网站上的许多示例 但我仍然无法指出导致某些写入的原因 这里我有一个用于图形的邻接矩阵 在分配时 我从 valgrind 获得无效写入 但整个程序中没有分段错误 我也得到无效的读取 但我认为
  • 为什么C中释放的结构体仍然有数据?

    当我运行这段代码时 include
  • 在C中,malloc(256)和malloc(sizeof(char)*256)等价吗?

    我看到人们经常编写 C 代码 例如 char ptr malloc sizeof char 256 这真的有必要吗 标准说sizeof char 1根据定义 这样写是不是有意义 char ptr malloc 256 是的 C 定义了siz
  • C语言中如何释放内存?

    我正在编写具有大量一维和二维数组的代码 我收到 错误 无法分配区域 我认为这是因为分配了太多内存 我使用 malloc 和 free 函数 但我不确定我是否正确使用它们 也许你知道我在哪里可以看到关于 C 内存管理的好例子 所以 我只是想让
  • 从 void* 到 char** 的转换无效

    自从我搞乱 C 代码以来已经有一段时间了 在 Ubuntu 下使用 gcc 编译 C 代码时出现以下错误 我用来编译代码的命令是 如果这些错误是由于我使用的编译器造成的 请让我知道如何消除该错误 gcc o runnable mycode
  • C/C++ 的多线程内存分配器

    我目前有大量的多线程服务器应用程序 并且我正在寻找一个好的多线程内存分配器 到目前为止 我在以下两点之间左右为难 太阳乌梅 谷歌的tcmalloc 英特尔的线程构建块分配器 埃默里 伯杰的宝藏 据我所知 hoard 可能是最快的 但我在今天
  • sbrk 在 malloc.c 中如何/在何处使用?

    我在 高级 Unix 编程 以及其他几本书 中读到 Linuxmalloc 使用Linux系统调用sbrk 向操作系统请求内存 我正在看 glibcmalloc c代码 我可以看到很多提及sbrk 在注释中 但没有在代码中直接引用 如何 在
  • 如何在c中创建一个n维数组

    我正在考虑编写一个函数 它接受 n 个参数并使用这些参数作为维度返回一个 n 维数组 现在我意识到一维和二维数组很容易用指针实现 对于二维数组 片段将类似于 标准方式 int x int temp x int malloc m sizeof
  • git add 错误:“致命:malloc,内存不足”

    当我尝试执行 git add 时 出现错误 致命 malloc 内存不足 我想系统显然已经耗尽了内存 但是有没有办法解决这个问题 我还运行 Windows Server 2003 并使用 msysGit 编辑 经过更多搜索后 我认为这是 g
  • 我真的需要 malloc 吗?

    据我了解 malloc是用来动态分配内存的 在我的代码中 我有时会调用以下函数 int memory get log unsigned char day unsigned char date unsigned char month char
  • 函数插入仅适用于 malloc 而不是 free

    我在通过使用函数插入来监视 malloc 和 free 时遇到了一个小问题 当仅对 malloc 执行函数插入时 它按预期工作 然而 当尝试插入 free 时 它 最终会陷入循环 我似乎 free 被递归调用 但我只是不知道为什么 这是 m
  • 如何从 .t​​xt 文件中读取已知数量的未知大小的字符串并将每一行存储在矩阵的一行中(在 C 中)?

    标题是不言自明的 我几乎可以肯定 最终结果不会是一个矩阵 因为每行都有不同数量的列 所以它更像是可变大小的数组的数组 按大小对片段进行排序 最大的在前 也很有趣 这是我到目前为止所尝试过的 int main char str MAXLEN
  • 为什么 new()/delete() 比 malloc()/free() 慢?

    为什么new delete 比malloc free 慢 EDIT 感谢到目前为止的回答 如果您有new 和delete 的标准C 实现规范 请指出 谢谢 看一下这段C代码 struct data pd malloc sizeof stru
  • 编译器优化对 malloc 的调用以返回更多弱对齐内存是否合法?

    假设我们有以下代码 include
  • malloc:***错误:已释放对象的校验和不正确 - 对象可能在释放后被修改

    我的 iOS 应用程序有一个大问题 它有时会崩溃 而没有详细的调试错误 堆栈跟踪为空 这是堆栈跟踪中仅有的两行 UIApplicationMain 中的 符号存根 UIHostedTextServiceSession DismissText
  • 使用静态指针的动态内存分配

    有人可以向我解释一下为什么下面的代码会这样工作吗 这里我已经初始化了outd作为文件中的静态指针code2 c 然后我动态地为其分配内存malloc 从单独文件中的主函数中一次又一次地调用它code1 c 它看起来整个数组以静态方式运行 因
  • 如何 free() 由 malloc() 分配的结构数组?

    我一直在研究一个使用结构作为字符串存储的项目 我声明了一个由 char 类型成员组成的结构 struct datastore1 char name 50 char address 50 char email 50 char number 5
  • 为什么这种故意错误地使用 strcpy 不会严重失败?

    为什么下面的C代码使用strcpy对我来说工作得很好吗 我试图通过两种方式让它失败 1 我尝试过strcpy从字符串文字到分配的内存 该内存太小而无法容纳它 它复制了整个事情并且没有抱怨 2 我尝试过strcpy来自一个不是的数组NUL 终

随机推荐

  • 图像处理的傅里叶变换理解

    傅立叶变换在图像处理中有非常非常的作用 因为不仅傅立叶分析涉及图像处理的很多方面 xff0c 傅立叶的改进算法 xff0c 比如离散余弦变换 xff0c gabor与小波在图像处理中也有重要的分量 印象中 xff0c 傅立叶变换在图像处理以
  • 傅里叶变换分类

    傅里叶变换 傅里叶变换 xff08 Fourier transform xff09 是一种线性的积分变换 xff0c 从时间转换为频率的变化 1 1 连续傅里叶变换 这是将频率域的函数F 表示为时间域的函数f xff08 t xff09 的
  • C++实现二维离散傅里叶变换

    在上一篇文章 C 43 43 实现一维离散傅里叶变换 中 xff0c 我们介绍了一维信号傅立叶变换的公式和C 43 43 实现 xff0c 并阐述了频域幅值的意义 一维傅立叶变换只适用于一维信号 xff0c 例如音频数据 心脑电图等 在图像
  • MFC显示JPG,bmp图片

    主要代码如下 xff1a 方法说明 显示JPG和GIF BMP图片 参数说明 CDC pDC 设备环境对象 参数说明 CString strPath 要显示的图片路径 参数说明 int x 要显示的X位置 参数说明 int y 要显示的Y位
  • MFC关于JPG图片显示处理的几个方式

    做远程视频监控项目 xff0c 接触较多图片处理方面问题 xff0c 作为学习做以下记录 xff1a 一 截图默认bmp格式转jpg压缩 采用jpglib库去实现 二 jpg图片接收后MFC显示 四种方式 MFC提供的CWnd只有默认加载B
  • opencv学 之图像傅里叶变换dft

    一 前言 接触了图像的傅里叶变换 xff0c 数学原理依旧不是很懂 xff0c 因此不敢在这里妄言 下午用Opencv代码实现了这一变换 xff0c 有一些经验心得 二 关键函数解析 2 1copyMakeBorder 扩展图片尺寸 傅里叶
  • UML轻松入门之动态建模

    在UML中 xff0c 静态建模可以描述系统的组织结构 xff0c 而动态建模则可以描述系统的行为和动作 在动态建模机制中 xff0c 以消息完成对象之间的交互 xff0c 用状态图 顺序图 协作图和活动图来描述系统的行为 消息 在面向对象
  • C++实现 (FFT)一维快速傅里叶变换

    一维离散傅里叶变换的公式为 xff1a 如果直接基于该定义进行编程实现 xff0c 则算法时间复杂度为O N2 具体的编程实现我们已经在 C 43 43 实现一维离散傅里叶变换 中介绍过了 当一维信号长度达到几十万个信号时 xff0c 当前
  • 信号傅里叶变换后的实数和虚数部分理解

    傅里叶 xff08 FFT DFT 傅立叶 Fourier xff09 傅里叶变换的结果为什么含有复数 xff1f 为什么傅里叶变换的结果含有复数成份 xff1f 看了很多关于FFT的资料 xff0c 现在看到一个资料说FFT转换的结果是实
  • 从头到尾彻底理解傅里叶变换算法

    http www xuebuyuan com 2052774 html 经典算法研究系列 xff1a 十 从头到尾彻底理解傅里叶变换算法 上 作者 xff1a July dznlong 二零一一年二月二十日 推荐阅读 xff1a The S
  • 一维傅里叶变换后的复数怎样理解?

    我刚开始学傅氏变换也有这样的疑问 xff01 首先回答问题一 xff1a 为什么一个实信号经过傅氏变换后 xff0c 再反变换回来得到的是一个复数 这是由于matlab计算引起的 xff0c 你在计算傅氏反变换后引入了复数 xff0c 最后
  • 二维傅里叶变换是怎么进行的?

    1 首先回顾一下一维FT 通俗来讲 xff0c 一维傅里叶变换是将一个一维的信号分解成若干个三角波 对于一个三角波而言 xff0c 需要三个参数来确定它 xff1a 频率 幅度 A xff0c 相位 因此在频域中 xff0c 一维坐标代表频
  • 傅里叶变换和逆傅里叶变换numpy

    理论基础 时域 xff1a 以时间为横坐标 频域 xff1a 以频率的倒数为横坐标 xff0c 可以看出 xff0c 频域更加简单 相位 xff1a 与时间差有关的一个概念 傅里叶说 xff0c 任何连续周期信号 xff0c 可以由一组适当
  • 复数的物理意义

    很不错的文章 xff01 xff01 复数最直观的理解就是旋转 xff01 4 i i 61 4 就是 4 在数轴上旋转了180度 那么4 i就是旋转了90度 另外 xff0c e t是什么样呢 xff1f 但当你在指数上加上i之后呢 xf
  • 动态初始化一维数组详解

    动态初始化一维数组 1 动态初始化一维数组 xff0c 会在堆内存中分配这个数组 并且数组中每一个元素都采用默认值 byte short int long 0 float double 0 0 boolean false char u000
  • c语言之 malloc函数详解 在堆中动态分配内存malloc和new的区别

    一 原型 xff1a extern void malloc unsigned int num bytes 头文件 xff1a include lt malloc h gt 或 include lt alloc h gt 注意 xff1a a
  • 8086汇编与c++编译器就内存方面的感想

    8086汇编中可以手动分配栈内存 xff0c 没有堆内存的概念 xff0c 而c 43 43 编译器中栈是系统分配的 xff0c 堆是手动分配的
  • 2-NoSQL(非关系型数据库)-入门概述

    1 NoSQL是什么 xff1f NoSQL xff08 Not only SQL xff0c 不仅仅是数据库 xff09 xff0c 泛指非关系型数据库数据库 xff0c 其数据存储不需要固定的模式 xff0c 无需多余操作就可以横向扩展
  • 指针类型和指针类型转换的理解

    前几天在判断 值相同的两个指针所指向的变量的值可以不同 这句话时 xff0c 发现自己对指针类型一些概念仅仅是记住了结论 于是查阅了一些资料 xff0c 记录一下一些与指针类型和指针类型转化相关的知识 一些用到的 开始之前 xff0c 先来
  • 指针的动态初始化malloc与销毁free

    指针动态初始化 xff1a int p 61 int malloc sizeof int 3 初始化为指向3个元素的数组 if p exit 1 这个地方一定要进行判断 xff0c 因为若动态初始化不成功 xff0c 在使用p 0 p 1