动态内存(一)使用动态内存

Pointers or C 英文版翻译

原文:11.1 Why Use Dynamic Allocation


11.1 为什么使用动态分配

当声明一个数组时,数组的大小必须作为编译期常量被给定。数组真正需要的大小是不知道的,直到运行的时候,因为空间的数量依赖与输入的数据。例如,一个计算学生成绩和平均成绩的程序可能需要储存一个班全部学生的数据,但是不同的班学生的数量不同。这些情况下,通常的方法是声明一个它所需要大小的数组。


提示

使用数组的这种方法的优点是简单,但是也有一些缺点。第一、在程序中这种声明是有人为的限制,他没法处理使用比他声明的大小还要大的问题。显而易见的解决方案是使用更大的数组,但是第二个问题变的更加糟糕。当元素的真实需要的数量较少时,这个巨型数组使用的内存绝大多数被浪费。第三个缺点是,当输入的数据的数量超过数组所能承载的数量时,程序必须用合理的方式去响应。它不应该以抛出一个异常而失败,它也不会打印一些看起来有效但是实际上是错的的答案。实现需求的逻辑很简单,但是“数组从来都不会越界”的假设误导他不去实现这种方法。


11.2 Malloc and Free

在C 库中提供了 mallocfree 两个函数,用来执行动态内存的分配和释放。这些函数维护一个可用的内存池。当一个程序需要增加内存时,程序调用malloc方法,这个方法从内存池中获得一块内存并且给程序返回一个指向这块内存的指针。这块内存没有经过任何初始化。如果内存被初始化是很重要时,你必须自己或者调用calloc方法初始化它。当之前分配的内存不在需要时,调用free把内存还给内存次,以供今后使用。


这两个函数的原型如下,在stdlib.h 中声明

void*  malloc(size_t size);
void   free(void*  pointer);

malloc的参数 size 是指需要内存的字节数。如果内存池中可用的数量满足需求,malloc返回指向被分配内存起始位置的指针。


malloc分配连续的内存块。例如,你请求100个字节的内存,那么你将得到令你满意的100个字节的连续内存,从来不会是2块或者更多块分散的内存块。实际上malloc可能分配比你请求的略大的内存。然而,这个行为依赖与具体的实现,所以你不能指望得到比你请求的内存多的内存。


如果内存池耗尽或者它没有足够大的内存会发生什么?在这种情况下,malloc会电泳操作系统获取一块更大的内存,并且在新内存块的开始位置分配。如果操作系统不能为malloc提供更多的内存,那么malloc返回一个UNLL指针。因此每次都检测通过malloc返回的指针是必要的,确保它不是空指针。


free的参数必须是NULL或者是之前通过malloc , calloc , 或者 realloc返回的值。给free 传入 NULL 是没有任何效果的。


malloc 怎么知道你想要在请求的内存中储存整数,浮点数,结构体还是数组?它并不知道 –正因为这个原因 malloc 返回一个void * 类型的指针。C标准声明void*可以转换为任意其他类型的指针。但是一些编译器,尤其是老式的编译器可能要求你使用强制转换。


在一些对边界对齐有要求的机器上,通过malloc返回的内存边界的开始位置总是满足对边界要求最严格的数据类型的要求。


译者:小风code
时间:2017-11-8

猜你喜欢

转载自blog.csdn.net/qq_33775402/article/details/78481418