Chinaunix首页 | 论坛 | 博客
  • 博客访问: 23150
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-01-06 08:09
个人简介

充实自己,努力工作

文章分类
文章存档

2014年(6)

我的朋友

分类: LINUX

2014-01-17 17:51:45

原文地址:动态内存分配 作者:我本痴情

一:传统数组(静态数组)的缺点    

  1:数组的长度必须事先指定,并且是常整数,不能是变量   int a[5];

  2:传统数组程序员无法由程序员释放,只能由系统释放。(并且只能在数组所在函数结束才能释放)

  3:数组的长度在函数运行期间不能动态的扩充和缩小

  4A函数定义的传统数组,在A函数结束时,在B函数中是不能使用的,因为已经释放。也就是传统数组不能跨函数。

区分:静态存储与内存的静态开辟

二:为什么要动态分配内存

用来解决传统数组的四个缺陷

三:动态内存分配举例,以及动态数组的构造

 方式:malloc函数,在堆开辟空间

    Int  i =5;  //静态分配

Int *p  = (int *) malloc(4); //动态分配   NULL  (void *)0

1malloc是由程序员在堆栈动态开辟空间

2:返回值开辟空间的首地址,但是类型是void *,需要强制类型转换

3:分配的内存空间应该能整除类型所占的字节数

4:包含头文件malloc.h

5:只能用freep)来释放p所指向的动态开辟的内存空间。

6:对动态内存空间的操作,用*p来操作。

7:可以用多个指针指向这个动态空间

8:当有多个指针只向这个动态空间时,只能用free一个指针,多次重复释放要被报错

9:可以将动态开辟的的内存指针作为函数参数

问题:p的分配类型是动态的还是静态的?当调用freep)后,p的内存空间会被释放么?

例子:动态构建一个一维数组:

#include 

#include 

/*

  动态构造数组

*/

int main(int argc, char *argv[]){

int len,i;

scanf("%d",&len);

int *p = (int *)malloc(4*len); //构造了一个一维数组,长度是4*len个字节

for(i=0;i < len;i++)

  p[i] = i;

    for(i=0;i < len;i++)

  printf("%4d",p[i]);

  free(p);

return 0;

}

动态扩充数组的长度,也就是在程序运行时动态扩充:realloc(首地址,总共字节数)

作用:将原来动态开辟的动态内存重新开辟一个字节数,如果这个数比以前的大,前面的数据保存。如果比原来的小,保留前面的数据。

#include 

#include 

/*

  动态构造数组,并实现扩充与缩小

*/

int main(int argc, char *argv[]){

int len,i;

scanf("%d",&len);

int *p = (int *)malloc(20); //构造了一个一维数组,长度是4*len个字节

if(len > 5){

  p = (int *)realloc(p,len*4);

}

for(i=0;i < len;i++)

  p[i] = i;

    for(i=0;i < len;i++)

  printf("%4d",p[i]);

  free(p);

return 0;

}

注意:扩充或者缩放的内存单元是新开辟的内存单元。这个过程中有值的拷贝过程。返回值是新开辟的地址空间首地址。

四:静态内存和动态内存的比较

静态开辟的内存:在栈中开辟,由编译器分配,由系统自动释放

动态开辟的内存:在堆中开辟,由程序员开辟,由程序员自动释放。

五:跨函数使用内存的问题

#include 

#include 

int main(int argc, char *argv[]){

void fun(int **);

int *p;

fun(&p); //要想在子函数修改p本身的值,只能发送p的地址

   printf("%d  ",*p);

return 0;

}

void fun(int **q){

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

  **q = 5;

}

阅读(1225) | 评论(0) | 转发(0) |
0

上一篇:程序员遇到bug时常见的30种反应

下一篇:没有了

给主人留下些什么吧!~~