Dynamic Memory

来源:互联网 发布:快鸟地图软件 编辑:程序博客网 时间:2024/05/01 23:40

Dynamic Memory

目录

    • Dynamic Memory
    • 目录
    • malloc
    • free
    • realloc
    • calloc


主要讨论三个函数,还有第四个函数,不过它只是其中一个的变种。

  • malloc(): 分配内存供使用
  • free(): 释放 malloc() 分配的内存
  • realloc(): 改变之前分配的内存的大小
  • calloc(): 与 malloc() 很像,区别只是它会先把分配的内存先清零

malloc()

当你使用 malloc() 时,它会分配你想要的内存。它的返回值是一个指针,指向一块内存。如果分配失败,返回 NULL。指针的类型是 void* 的,所以你可以强转成任何你想要的类型。

malloc() 操作的内存是以 byte 为单位的,如果想分配更大的内存空间(比如,”给我分配 12 个 int 的空间”),那么就要使用 sizeof() 操作符来决定你需要多少 byte 的空间,比如:

int *p;p = malloc(12 * sizeof(int)); // 给我分配 12 个 int 内存的空间

分配好了之后,就可以像一般指针一样来引用(reference)这个指针了,毕竟,呃…它就是个指针。

当然,最好在使用它之前,校验一下它的有效性,因为可能 malloc() 会返回 NULL:

int *p;p = malloc(12 * sizeof(int)); // 给我分配 12 个 int 的内存空间if (NULL == p) {    printf("We're probably out of memory!\n");    exit(1);}

或者是一行搞定:

int *p;if (NULL == (p = malloc(12 * sizeof(int)))) { // 给我分配 12 个 int 的内存空间    printf("We're probably out of memory!\n");    exit(1);}

记住:malloc() 是在堆上分配内存,而且只有两种方式能回收这些内存:1) 程序运行结束,或者 2) 使用 free() 来释放 malloc() 的内存。如果程序运行了很长时间,并且一直在 malloc() 而且也没有在该 free() 的地方使用 free(),那么就会造成内存泄露。

避免内存泄漏。用完 malloc() 的内存,一定要 free()


free()

释放动态分配的内存? 使用 free() 即可!
free() 需要一个参数,这个参数就是由 malloc() (或者 calloc()) 返回的指向分配的内存的地址的指针。free() 会释放掉这个内存中所有的数据。free() 之后的内存,千万别用,谁用谁知道!

用法如下:

int *p;p = malloc(12 * sizeof(int)); // 分配了 12 个 int 的内存空间// 在这期间你可以操作 p 指向的内存free(p); // 释放掉 

realloc()

realloc() 是这样一个函数: 它持有由 malloc() (或者 calloc()) 分配的内存并且改变这块内存的大小。或许一开始你只需要 100 个 int 的内存,但是现在需要 200 个了。此时你就可以使用 realloc() 来获得需要的内存。

但是,需要注意的是:如果 realloc() 不能再当前的内存块的基础上扩展大小,那么它会把原先内存里的内容都复制到新的内存上,这就囧了,耗时间。

这意味着: 要谨慎的使用 realloc()
通常程序会跟踪还有多少的可用空间,一旦要发生溢出,那么就使用 realloc()。

#include <stdlib.h>#define INITIAL_SIZE 10#define BUCKET_SIZE 5static int data_count; // how many ints we have storedstatic int data_size;  // how many ints we *can* store in this blockstatic int *data;      // the block of data, itselfint main(void) {    void add_data(int new_data); // function prototype    int i;    // first, initialize the data area:    data_count = 0;    data_size = INITIAL_SIZE;    data = malloc(data_size * sizeof(int)); // allocate initial area    // now add a bunch of data    for(i = 0; i < 23; i++) {        add_data(i);    }    return 0;}void add_data(int new_data) {    // if data_count == data_size, the area is full and    // needs to be realloc()'d before we can add another:    if (data_count == data_size) {        // we're full up, so add a bucket        data_size += BUCKET_SIZE;        data = realloc(data, data_size * sizeof(int));    }    // now store the data    *(data+data_count) = new_data;    // ^^^ the above line could have used array notation, like so:    //  data[data_count] = new_data;    data_count++;}

上面这个例子中,只有当 1) 初始的 10 ints 的空间被填满以及 2) 之后的 5 ints 被填满的时候,才会使用 realloc()。总比每次添加一个 int 就调用一次 realloc() 好吧。


calloc()

calloc() 与 malloc() 只有两个区别,除此之外,是一样的:

  • calloc() 把先把分配的内存清零而 malloc() 不会
  • calloc() 需要两个形参而 malloc() 只需要一个

calloc() 的两个形参分别是 1) 即将存在于内存中的元素个数,以及每个元素的大小。这与 malloc() 很像:

// malloc()p = malloc(12 * sizeof(int));// calloc() p = calloc(12, sizeof(int)); // 内存先清零

calloc() 返回的指针也可以与 realloc() 和 free() 一起使用,与 malloc() 返回的指针是一样的。

使用 calloc() 的一个缺点就是清空内存是需要时间的,大多数情况下,并不需要清空,因为肯定会在分配的内存是上执行写操作的。但是如果你发现 使用 malloc() 得到一片内存之后,又要对这片内存进行清空,那么可以使用 calloc() 一步到位。

0 0
原创粉丝点击