动态内存/动态数组

一、malloc

  1.常用表达式:int *p = (int *)malloc(n*sizeof(int));  

    为20个char*分配内存 char **p = (char **)malloc(20*sizeof(char*));   

  2.malloc()内是所需申请的字节数,而malloc本身并不知道要申请什么类型的字节,malloc本身的类型:

void *malloc( size_t size );若要返回指针类型,要使用强制类型转换。

  3.p一定是指向指针的开头,不能p++,不然指针的指向发生移动,free崩溃

  4.malloc在堆里,堆的内存:1G左右

  5.栈和堆的区别

栈:由系统自行管理

堆:程序自行管理

  6.malloc申请内存,利用free释放,如果没有释放,则出现内存泄漏

  7.出现内存泄漏,则可用内存越来越少,设备速度越来越慢

  8.内存泄漏很难解决的两点原因

(1)程序退出,操作系统将程序消耗的内存全部回收

(2)关机。所有内存回到初始状态

  9.安装vld小软件,引用#include<vld,h>检测内存泄漏

二、calloc

1.int *p = (int *)calloc(10,sizeof(int));  

//10表示数组长度,sizeof(int)表示每个格子的大小,用的不多,实际上10*sizeof(int)就是malloc的表达,比malloc多了一步将数组初始化为0

三、realloc

1.realloc:扩容    malloc想扩容,则用realloc

int *q = (int *)malloc(20*sizeof(int));   //创建新家

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

{

      *q[i] = *p[i];                       //搬家

}

     free(p);                              //释放旧地址

    p = q;                                //更新新地址

    q = NULL;                             //浅拷贝发生错误,多个指针不能指向同一个内存,所以q = NULL


    free(p);                              //若不加q=NULL,则free崩溃(重复释放)                                                              

{ free(q);

2.int *p = (int *)realloc(20*sizeof(int));          //新的大小   重新分配20个格子的内存

3.若int *p = (int *)realloc(5*sizeof(int));          //即缩小容量会怎样?

        realloc可以对给定的指针所指的空间进行扩大或者缩小,无论是扩张或是缩小,原有内存的中内容将保持不变。当然,对于缩小,则被缩小的那一部分的内容会丢失。

4.(1)windows编译器:重新申请一块“地”

   (2)gcc:补加一块“地”

四、free

1.free如何得到长度信息?

malloc分配了两个空间,一个是管理空间(记录了管理信息),一个是实际空间,管理信息由结构体保存,如下:

struct mem_control_block {
    int is_available;    //这是一个标记?
    int size;            //这是实际空间的大小
    };

而在结构体里记录了malloc申请的实际空间的大小,free释放的是指针指向的内存大小,而不是指针,指针在程序结束时销毁,由于free释放了它指向的内存大小,所以它最后返回一堆垃圾,free的源代码:

void free(void *ptr)
    {
            struct mem_control_block *free;
            free = ptr - sizeof(struct mem_control_block);
            free->is_available = 1;
            return;
    }

函数第二句中free的值减去一个结构体大小,释放了实际空间,让指针指向管理空间,然后管理空间里的信息会告诉操作系统释放实际内存的大小等信息。

http://blog.csdn.net/r91987/article/details/6337032

2.free崩溃的原因?

(1)越界

(2)指针的指向发生移动

(3)重复释放

五、一些小知识

1.C语言中三大缺点

(1)内存泄漏

(2)内存越界

(3)数组太丑

其它变量的写法:int a = 0;  char *p = &a;  都是先分配好内存空间,再命名,而int Arr[10]则是先命名,再分配内存空间。

比如int Arr[10];原本按照定义是这样写的int [10]Arr;又例如

typedef unsiged long long uint64;

typedef int * Pint;
typedef int Arr[10];
typedef int (*Pfun)();

2.int *p:不能用sizeof(p)/sizeof(p[0]); 

//error  结果是1,并不是想要求得的P的长度,如果P是数组则可用该公式

六、malloc的程序:用筛选法找出素数

#define NUM 1000        //bug的主要来源
void SiftPrime(int n)
{
int *p = (int *)malloc(n*sizeof(int));
 assert(p != NULL);
 int i;
 for(i=0;i<n;i++)
 {
  p[i] = 1;    //默认为1,是素数记为1,不是素数记为0
 }
 p[0] = 0;
 p[1] = 0;

 for(i=2;i<=sqrt((float)n);i++)
 {
  for(int j=i+1;j<n;j++)
  {
   if(j%i == 0)
   {
    p[j] = 0;
   }
  }
 }

 for(i=0;i<n;i++)
 {
  if(p[i] == 1)
  {
   printf("%d\n",i);
  }
 }
 free(p);
}

int main(void)
{
 SiftPrime(20);

 return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@所谓伊人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值