c语言学习之基础知识点介绍(十九):内存操作函数

一、malloc函数

/*
    首先需要导入头文件 #include <stdlib.h>
    malloc
       void*  malloc(n);

        n是字节大小
        开辟堆空间,开辟的字节数以n为准
        返回的是开辟空间的首地址
        void*是万能指针,也就是说你可以用任意类型的指针去指向

*/

 //malloc用法

 int *p =  malloc(sizeof(int));

  *p = 30;

 printf("%p    %d\n",p,*p);//0x100105490

   char *pc = malloc(sizeof(char)*4);

    pc[0]= ‘a‘;

   pc[1] = ‘b‘;

  pc[2] = ‘c‘;

   pc[3] = ‘\0‘;

   printf("%s\n",pc);

   char *pc = malloc(4);

   *pc = ‘a‘;

   *(pc+1) = ‘b‘;

  *(pc+2) = ‘c‘;

    *(pc+3) = ‘\0‘;

  printf("%s\n",pc);

  char *pc = malloc(4);
   char *temp = pc;

   *pc = ‘a‘;
   pc++; //自身+1

  *pc = ‘b‘;

  pc++;
 *pc = ‘c‘;

   pc++;
    *pc = ‘\0‘;

  printf("%s\n",temp);

  char *pc = malloc(1);

   *pc = ‘h‘;

 printf("%c\n",*pc);

二、calloc函数

//calloc用法

    int nums[3] = {10,20,30};//在栈区
  int *p = calloc(4, 3);//在堆区
 p[0] = 10;
  p[1] = 20;
p[2] = 30;
 for (int i =0; i<3; i++) {
   printf("%d\n",p[i]);
  }

    int *p = calloc(4, 3);//在堆区

    *(p) = 10;
    *(p+1) = 20;
    *(p+2) = 30;

    for (int i =0; i<3; i++) {

        printf("%d\n",p[i]);
    }

malloc和calloc的区别:
      malloc不会初始化,会有垃圾值,calloc会初始化为0

char *pch = malloc(100);

    for (int i =0; i<100; i++) {

        printf("%d  ",*(pch+i));
    }

    printf("\n------------分割线-------------\n");

    char *pch2 = calloc(1, 100);

    for (int i =0; i<100; i++) {

        printf("%d  ",*(pch2+i));
    }

三、realloc函数

/*
当自己手动开辟出来的空间不够用了,这个时候我们需要去扩容,就得用到realloc这个函数。

        realloc:
                realloc(要扩容的空间首地址,操作后的字节大小);

        作用:把你传入的空间进行扩容或者缩小,操作后的字节大小以后面的参数为准。

        注意:用realloc函数的时候最好再用指针变量接收一下返回值。
                    因为你扩容的时候,很可能是系统帮你在一块新的足够大的空间里面进行扩容了,那样空间首地址就发生改变了。

*/

   //realloc的使用
    char *p = malloc(100);

    *p = "的手机客户端还是把空间分布的刷卡缴费多少部分科技的设备房间号多少功夫空间都是给我看一个";
    //所以要重新接收一下
    p = realloc(p, 1000);//放大
    p = realloc(p, 50);//缩小

四、内存泄露

/*
内存泄露:
        内存容量有限,然后如果你不及时回收不要用的空间,而是一直开辟新的空间,那么内存就会不够用,就叫内存泄露(像水杯装水一样)。

        代码里面:某块空间一直占据,没被回收就叫内存泄露。

回收自己开辟的堆空间:
            free:
                free(要回收的空间首地址);

 野指针:指向的是已被回收的空间的指针叫野指针。指向不可用的内存空间叫野指针。

 防止野指针:
        就是在回收后,立即将指针变量置为NULL。
*/
int *p = malloc(4);//内存泄露

    //因为没有对p指向的堆空间进行回收,所以就内存泄露

    //那么程序自己怎么回收??

    free(p);//此时p指向的空间首地址就被回收了,此时p变为野指针

    p = NULL; //p指向的空间被回收后,要立即把p置为NULL,防止野指针错误
时间: 2024-10-10 13:38:45

c语言学习之基础知识点介绍(十九):内存操作函数的相关文章

c语言学习之基础知识点介绍(三)

本节继续介绍c语言的基础知识点. scanf函数:用来接收用户输入的数据. 语法:scanf("格式化控制符",地址列表); 取地址要用到取地址符:&(shift+7) 例如:int num =0; csanf("%d",&num);printf("num = %d \n",num); 注意:格式化控制符前面要求输入什么类型的数据,那么地址列表那里就必须只能放相应类型变量地址.输入值的时候可以指定输入值的分隔符, 也可以 默认用回

c语言学习之基础知识点介绍(二十):预处理指令

一.预处理指令的介绍 预处理命令:在编译之前触发的一系列操作(命令)就叫预处理命令. 特点:以#开头,不要加分号. #include: 文件包含指令 把指定文件的内容复制到相应的位置 #define: #define 宏名 替换的值; 宏.宏定义或者还叫宏代换. 作用:就是在编译之前把所有用到这个宏的地方,替换成你指定的东西 规范:宏名大写,可以跟变量区分开来 之前学的宏: INT32_MAX INT32_MIN 宏不占据内存空间,只是帮你做简单的替换. 注意: 1.宏只是简单的替换,不参与编译

c语言学习之基础知识点介绍(十):内存空间模型、地址解释及指针变量

一.内存 /* 内存: 存在内存里的. 内存分了N多个小空间,每个小空间1个字节 每个小空间有它自己的地址.每个地址之间差1 int类型占用4个字节,等于占了4个空间(有4个地址),不需要记住4个地址,而记住首地址就行了(因为首地址相当于入口或者生活中的门) 指针: 指针就是地址,地址就是指针. 地址:内存的地址 内存中的地址: 其实也是从1开始编号,然后一直自增 1M内存,1024个地址 0x7fff5fbff7cc:这叫16进制 十进制:逢10进1 有:0 1 2 3 4 5 6 7 8 9

c语言学习之基础知识点介绍(十八):几个修饰关键字和内存分区

一.几个修饰关键字 全局变量: 全局变量跟函数一样也分为声明和实现.如果是全局变量,实现在它调用之后,那么需要在调用之前进行声明.注意:全局变量的声明只能写在函数外,写在函数就不是全局变量了而是局部变量. static: 修饰局部变量:      可以把局部变量变为静态变量.意思就是:程序一启动就加载,程序退出才会回收空间(跟全局变量很像) .   静态变量:用static修饰的局部变量就叫静态变量. 修饰全局变量:            让全局变量只能在本模块中访问.     修饰函数:   

c语言学习之基础知识点介绍(一)

本系列是为了学习ios做准备的,也能作为c语言入门的教程看看. printf函数: printf函数作为输出语句,主要的作用个就是输出用户想输出的语句. 例如:printf("我是一个大帅哥~~"); printf("数字1=%d,数字2=%d",10,20);//%d接下来会在一起解释. /* %d:填入int,short型的数据,例如printf("数字1=%d,数字2=%d",10,20); %ld:填入long型的数据,例如printf(

oc语言学习之基础知识点介绍(四):方法的重写、多态以及self、super的介绍

一.方法重写 /* 重写:当子类继承了父类的方法时,如果觉得父类的方法不适合,那么可以对这个方法进行重新实现,那么这个就重写. 注意:也就是说,一定只能发生在父类和子类关系中. 然后是子类重新实现父类的方法,绝对不是再写一个自己类的方法. 代码中原话叫:子类重写父类方法. 因为父类定义的方法不一定适用于子类. 注意:如果有重写,那么调用的是自己重写后的方法,如果没有重写,那么就调用的是父类的方法. 所以我们方法有一个执行的过程: 1.先去自己类里面找这个方法,如果找到就执行. 2.如果没找到,就

oc语言学习之基础知识点介绍(五):OC进阶

一.点语法介绍 /* 以前封装后,要给属性赋值,必须调用方法 这样做,有两个缺点: 1.代码量多,调用方法要写的东西多. 2.看起来并不像是给属性赋值,也不像取值. 我们用点语法就可以更好的解决! 点语法的语法: 对象.属性; 注意:这里的属性不需要加_ 对象.属性 = 值; 点语法的本质: 其实就是调用getter或者setter方法. 点语法注意事项: 1.在类的方法里面如果用self.age 这个是调用方法,self->_age 是直接调用成员变量. 2.千万记得不要在setter或者ge

c语言学习之基础知识点介绍(十三):枚举的介绍和使用

一.枚举的介绍 /* 枚举:限制的待选项. 语法: enum 枚举名{ 选项1, 选项2, 选项3, ........ 选项n }; 注意:枚举中,选项之间用 , 隔开,最后一个不用加 , :并且枚举已 ; 结尾. 声明枚举变量: enum 枚举名 变量名 ; 例如:enum qHand qh; 赋值: 1.先声明,后赋值 enum 枚举名 变量名 ; 变量名 = 枚举项; 例如: enum qHand qh; //qh是变量名,enum qHand 是类型 qh = 石头; 2.声明的时候初始

c语言学习之基础知识点介绍(五)

本节主要说关系运算式和逻辑运算式. 一.关系运算式 1.等于(==):判断左边的表达式是否等于右边的表达式 2.大于(>):判断左边的表达式是否大于右边的表达式 3.大于等于(>=):判断左边的表达式是否大于等于右边的表达式 4.小于(<):判断左边的表达式是否小于右边的表达式 5.小于等于(<=):判断左边的表达式是否小于等于右边的表达式 6.不等于(!=):判断左边的表达式是否不等于右边的表达式 //注意:c语言中,关系运算所得结果只有0和1,0代表false(假),1代表tr