1. C语言定义1个数组的时候, 必须同时指定它的长度.

例如:

int a[5]={1,2,3,4,5};    //合法
int b[6];   //合法int c[];    //错误   因为没有指定长度

但是下面语句是正确, 它隐形定义了数组的长度, 就是赋值元素的个数

int d[] ={4,5,6,7,8,9}    //合法 长度为6


2. 静态数组

        什么是静态数组,  其实上面合法定义的数组都是静态数组.
        静态数组并不是指数组里面的元素是静态的,  上面的数组都可以修改指定元素的指
        而是指数组的元素个数是静态的,  也就是某1个静态数组一旦被定义, 那么在程序运行结束的这段时间里它的长度的都是不变的.
        也就是说当你定义1个 静态数组a[5]
         int a[5]={1,2,3,4,5};
        
         你就不能修改a 的长度了.

3.动态定义数组的个数

         有时我们需要1个数组, 但是数组的元素个数不是固定的, 是个变量,  那么我们是否可以利用如下语句

 int i = 7;int a[i];    //定义1个长度为i的数组?

上面的写法可以能在java .net 里面是可行的, 但是c语言里是不合法的, 不能这样定义1个数组.  数组的长度必须是1个常量.

但是经本人测试,  上面的写法已经被最新的gcc支持了 囧

正确的写法:

int len =7;
int * a = (int *) malloc (sizeof(int) * len);

int * a 就是顶定义1个int类型的指针啦.
                其中 sizeof(int) 就是4 (byte) 啦  ,  
                 malloc (sizeof(int) * len)        就是在内存划出 4* len = 28个字节的内存, 并返回第1个字节(最小内存单位)的地址
               
                malloc函数是返回1个地址的, 但是只有地址是没有意义的.  因为要把这个地址赋值给1个int类型指针的话,要将其格式化.

所以malloc 前面要加上(int *) 就是把malloc 返回的地址格式化成1个 int类型的地址.

可以理解成这个int类型的地址是4个字节1个单位的,  只要获得这个地址, 就获得后面3个地址的内容啦.

所以上面蓝色的语句就的得到了1个指
         正确的写法:向 1个 长度为7的int类型数组指针a.

后面就可以把a 当作一般的数组名a来处理了.

最后注意一点, 使用malloc函数 , 必须引用malloc.h  或者 stdlib.h头文件.

4.动态数组占用的释放
                 定义1个静态数组int a[7],  那么在函数结束被调用或程序结束前的时间里, 这28个字节是容易被这个数组占用的.
 
                  而动态分配(malloc函数分配)的内存 在程序运行的时间内可以被释放.  然后被其他对象使用.

例如:

                 int len =7;int * a = (int *) malloc (sizeof(int) * len);// 这里可以把数组a 当作普通数组来使用free(a);   //释放这个数组a所占的28个字节的内存.//注意 是释放指针a所指向的内存, 而不是释放指针a本身占用的内存.// 注意不能释放静态变量或数组的空间.// 注意 经由malloc 分配的动态内存. 必须手动释放

这样的话. 优点很明显. 因为可以动态分配和释放, 比其静态定义要节省内存啊.

5.动态数组长度的增加.
               
这个就是动态数组跟静态数组区别最大的地方了, 动态数组的长度可以改变啊.
                接上面的例子

 int len =7;int * a = (int *) malloc (sizeof(int) * len);

上面定义了1个长度为7 的动态数组,  这时我发现这个数组不够用了, 想给它加1个元素,值是40,也就是令他的长度+1
              
                 直接

*(a+7) = 40; //合法, 也可能通过编译和执行.  但是这个是错误的写法.

为什么说上面的写法是错误的呢,  因为我们只给指针a 分配了1个字节为28byte的连续内存空间.
                就是 从a[0] 到 a[6]了
                那么a[7]是什么呢,  明显就是a[6]后面接着的4个字节的内存空间啊. 
               但是这个空间有可能被其他对象或其他程序正使用中的, 以后也可能被使用,  这样未执行分配指令就直接使用的话就很有可能改变了其他对象或程序中的内存内容,  这就是所谓的不安全行为.

那应该怎么做?
               就用到另一函数  realloc()   重新分配指针a所占的长度.

例如:

  int len =7;int * a = (int *) malloc (sizeof(int) * len);len++;int * aold = a;            //重新分配前保存a的地址  这个是多余的a = (int *)realloc(sizeof(int)* len);   //重新分配28+4 = 32字节内存给数组a

我们来分析一下上面4条语句
                 前面两句定义了1个长度为7的int 类型数组, 每个元素的字节长度是4, 所以共占28byte 内存.
                 第3句长度变量+1
                 第4句 分两种情况:
                            1) 假如数组a 内存里接着的4个字节还没被其他对象或程序占用, 那么就直接把后面4个字节加给数组a, 数组前面7个旧的元素的值不变,  数组a的头部地址也不变.

2) 假如数组 a内存里接着的4个字节已经被占用了, 那么realloc 函数会在内存其他地方找1个连续的32byte 内存空间, 并且把数组a的7个旧元素的值搬过去,  所以数组a的7个旧元素的值也不变, 但是数组a的头部地址变化了.  但是这时我們无需手动把旧的内存空间释放. 因为realloc 函数改变地址后会自动释放旧的内存, 再手动释放程序就会出错了, 我被坑过啊

下面的代码就是多余, 也是错误的.

  if (aold != a){            //如果a的地址改变了, 代表内存在另外1个地方划分1个新的内存空间free(aold);          //把旧空间释放}

但最终效果都一样的, 就似是我们可以动态地给动态数组a增加多1个元素的内存空间.

注意: realloc 函数不能用在静态数组的指针上,  即使通过编译. 执行时也会出错.

 5.一个简单的例子程序:

int malloc_3(){int len = 7;int * a = (int *)malloc(sizeof(int) * len);int i;for (i=0; i <len ; i++){a[i] = (i+1)*2;} i = p_array_int_1(a,len); //a function to print the array which defined by user    printf("address is %p\n", a);len++;//a = (int *)realloc(a, sizeof(int)* (len));i = re_malloc(&a, len);a[len-1]= 40;i = p_array_int_1(a,len); //a function to print the array which defined by user  printf("address is %p\n", a);free(a);return 0;
}int re_malloc(int ** pa, int len){int * pold;*pa = (int *)realloc(*pa, sizeof(int)* (len));if (pold != *pa){free(pold);}return 0;
}

输出:

C语言 利用malloc()和realloc()动态分配内存相关推荐

  1. c语言释放内存函数,【C语言】内存分配函数malloc/ calloc/ realloc及内存释放free

    前言: 内存区域划分与分配: 1.栈区(stack)--程序运行时由编译器自动分配,存放函数的参数值,局部变量的值等,程序结束时由编译器自动释放. 2.堆区(heap) -- 在内存开辟另一块存储区域 ...

  2. malloc()动态分配内存

    首先写一段示例代码: #include <stdio.h> #include <malloc.h> int main(void) {int a[5]={4,10,2,8,6}; ...

  3. 易语言利用WMI取磁盘CPU内存显卡信息源码

    WMI 是 Windows Management Instrumentation (Windows管理工具)的缩写,是内置在操作系统中核心的管理支持技术,通过它可以访问.配置.管理和监视几乎所有的 W ...

  4. c语言动态分配输出学生成绩,C语言之:结构体动态分配内存(利用结构体数组保存不超过10个学生的信息,每个学生的信息包括:学号、姓名和三门课(高数、物理和英语 )的成绩和平均分(整型)。)...

    题目内容: 利用结构体数组保存不超过10个学生的信息,每个学生的信息包括:学号.姓名和三门课(高数.物理和英语 )的成绩和平均分(整型). 编写程序,从键盘输入学生的人数,然后依次输入每个学生的学号. ...

  5. c语言malloc,calloc,realloc函数介绍

    malloc,calloc,realloc动态内存管理函数的出现解决了在某些c语言标准中不能使用变长数组的问题 这三个函数的使用需要头文件stdlib.h,这些函数开辟的空间在堆区,系统不会自动释放, ...

  6. 【C语言】深入浅出理解指针及内存与指针的关系(详细讲解+代码展示)

    目录 概述 内存 内存含义 内存作用: 物理存储器和存储地址空间 物理存储器:实际存在的具体存储器芯片. 存储地址空间:对存储器编码的范围. 内存地址 指针和指针变量 指针基础知识 指针变量的定义和使 ...

  7. Linux倒序赋值用molloc函数,请教一个C语言函数malloc的问题

    halazi100 于 2014-11-27 16:24:42发表: malloc和free的原理 一.malloc()和free()的基本概念以及基本用法: 1.函数原型及说明: void *mal ...

  8. realloc动态内存调整探究

    1 关于动态内存 C程序使用malloc.realloc等内存申请函数在堆上分配和释放内存的. 程序在执行期间有两个内存区域,一个是内存区域是栈(stack),另一个是堆(heap).栈中的空间分配给 ...

  9. 利用malloc函数分配二维数组

    利用malloc()函数分配的内存是连续的的,我们可以先分配二维数组的行(即行指针),然后利用分配的行指针,再分配列指针.咱们以分配一个4x5的二维数组为例,如下图(): 1.先分配连续的4块内存作为 ...

最新文章

  1. [更新问题]无法在安装新的版本前,为“./boot/vmlinuz-2.6.24-19-generic”做一个符号链接备份...
  2. UVA10780幂和阶乘
  3. 【WPF】监听WPF的WebBrowser控件弹出新窗口的事件
  4. Java常见排序算法之直接选择排序
  5. 预警展示样式html,纯css3 Tooltip工具提示样式
  6. 萝卜源码前后端源码 附打包APP的教程
  7. Centos、Ubuntu的区别
  8. Sass--伪类嵌套
  9. 【博客美化】02.公告栏显示个性化时间
  10. 用PyTorch实现一个卷积神经网络进行图像分类
  11. vue-cli --动态配置Ip地址,而不需要每次都打包
  12. Android PreferenceScreen介绍
  13. linux shell 数字雨,cmd命令如何实现数字雨的效果
  14. 基于QT的UDP测试工具
  15. 仿金蝶进销存源码(含数据库脚本)
  16. 函数的正交与向量正交
  17. selenium:如何模拟鼠标拖放(drag and drop)
  18. 解读txt文件中的乱码
  19. 欲练神功必先自宫,String 自宫后“不可变性”到底有啥好处?
  20. 【安全头条】美国政府起诉 Kochava 出售敏感的地理位置数据

热门文章

  1. [密码学] 密钥分发
  2. [密码学] 双重与三重DES
  3. Kubernetes实用技巧
  4. QT5对话框的中文字符串【乱码】 (error: C2001: 常量中有换行符)
  5. (34)内核编程基础
  6. angr学习笔记(9)(添加约束)
  7. 汇编层探索与讨论c++引用
  8. 【网络安全】详细记录一道简单面试题的思路和方法
  9. c++11 变长参数的使用(制作一个多参数多类型求和函数)
  10. Windows保护模式学习笔记(八)—— 页目录表基址/页表基址