Pointers on C——11 Dynamic Memory Allocation.3

来源:互联网 发布:金山软件股价 编辑:程序博客网 时间:2024/06/05 02:31

11.5 Common Dynamic Memory Errors


There are many errors that can occur in programs that use dynamic memory allocation. These include dereferencing NULL pointers, going outside die bounds of the memory that was allocated, freeing memory blocks that were not dynamically allocated, attempting to free a portion of a dynamic block, and continuing to use dynamic memory after it has been freed.

在使用动态内存分配的程序中,常常会出现许多错误。这些错误包括对NULL 指针进行解引用操作、对分配的内存进行操作时越过边界、释放并非动态分配的内存、试图释放一块动态分配的内存的一部分以及一块动态内存被释放之后被继续使用。


The most common error with dynamic memory allocation is forgetting to check whether the requested memory was allocated. Program 11.1 presents a technique that makes this error checking almost foolproof The MALLOC macro takes the number of elements and type of each element, computes the total number of bytes needed, and calls alloc to obtain the memory.alloc calls malloc and then checks to make sure that the pointer returned was not NULL.

动态内存分配最常见的错误就是忘记检查所请求的内存是否成功分配。程序1 1.1展现了一种技巧,可以很可靠地进行这个错误检查。 MALLOC 宏接受元素的数目能及每种元素的类型,计算总共需要的内存字节数,并调用alloc 获得内存。 alloc 调用malloc 并进行检查,确保返回的指针不是NULL。


The final piece of this puzzle is the very first #define. It prevents accidental calls directly to malloc by substituting junk into the program. If an accidental call is made, the program will not compile due to syntax errors. The #undef is needed in alloc so that it can call malloc without error.

这个方法最后一个难解之处在于第1 个非比寻常的#define 指令。它用于防止由于其他代码决直接塞入程序而导致的偶尔直接调用malloc 的行为。增加这个指令以后,如果程序偶尔调用了malloc ,程序将由于语法错误而无法编译。在alloc 中必须加入#undef 指令,这样它才能调用malloc 而不至于出错。


The second biggest source of error with dynamically allocated memory is going outside of the bounds of the memory that was allocated. For example, if you have obtained an array of 25 integers, accessing elements with subscripts less than zero or greater than 24 can cause two types of problems.

动态内存分配的第二大错误来源是操作内存时超出了分配内存的边界。例如,如果你得到一个25 个整型的数组,进行下标引用操作时如果下标值小于0或大于24 将引起两种类型的问题。


The first problem is obvious; the memory being accessed might be holding some other variable. Changing it here will destroy the variable, and changing the variable will destroy any value you store here. These kinds of bugs are very difficult to track down.

第1 种问题显而易见:被访问的内存可能保存了其他变量的值。对它进行修改将破坏那个变量,修改那个变量将破坏你存储在那里的值。这种类型的bug 非常难以发现。


The second problem is not so obvious. Some implementations of malloc and free keep the pool of available storage as a linked list. Modifying location outside the bounds of allocated memory can corrupt this list, which can cause exceptions that terminate the program.

第2 种问题不是那么明显。在malloc 和free 的有些实现中,它们以链表的形式维护可用的内存池。对分配的内存之外的区域进行访问可能破坏这个链表,这有可能产生异常,从而终止程序。


/*

** Definitions for a less error-prone memory allocator.

定义一个不易发生错误的内存分配器。

*/

#include <stdlib.h>

#define malloc DON'T CALL malloc DIRECTLY!

#define MALLOC(num,type) (type *)alloc( (num) * sizeof(type) )

extern void *alloc( size_t size );

Program 11.1a Error checking allocator: interface                         alloc.h

错误检查分配器:接口

/*

** Implementation for a less error-prone memory allocator.

*/

#include <stdio.h>

#include "alloc.h"

#undef malloc

void *

alloc( size_t size )

{

void *new_mem;

/*

** Ask for the requested memory, and check that we really

** got it.

*/

new_mem = malloc( size );

if( new_mem == NULL ){

printf( "Out of memory!\en" );

exit( 1 );

}

return new_mem;

}

Program 11.1b Error checking allocator: implementation                   alloc.c

程序11.1b 错误检查分配器:实现

/*

** A program that uses the less error-prone memory allocator.

*/

#include "alloc.h"

void

function()

{

int *new_memory;

/*

** Get space for a bunch of integers

*/

new_memory = MALLOC( 25, int );

/* ... */

}

Program 11.1c Using the error checking allocator                          a_client.c

程序11.1c 使用错误检查分配器


When a program that uses dynamically allocated memory fails, it is tempting to blame the problems on malloc and free. They are rarely the culprit, though. In practice, the problem is nearly always in your program and is frequently caused by accessing data outside of the allocated memory.

当一个使用动态内存分配的程序失败时,人们很容易把问题的责任推给malloc 和free 函数。但它们实际上很少是罪魁祸首。事实上,问题几乎总是出在你自己的程序中,而且常常是由于访问了分配内存以外的区域而引起的。


Different errors can occur when using free. The pointer passed to free must be a pointer that was obtained from malloc, calloc, or realloc. Calling free with a pointer to memory that was not dynamically allocated can cause the program to terminate either right away or at some later time. Similar problems can be caused by attempting to free only a portion of a dynamically allocated block, like this:

当你使用free 时,可能出现各种不同的错误。传递给free 的指针必须是一个从malloc、calloc或realloc 函数返回的指针。传给free 函数一个指针,让它释放一块并非动态分配的内存可能导致程序立即终止或在晚些时候终止。试图释放一块动态分自己内存的一部分也有可能引起类似的问题,像下面这样:


/*

** Get 10 integers

*/

pi = malloc( 10 * sizeof( int ) );

...

/*

** Free only the last 5 integers; keep the first 5

*/

free( pi + 5 );


Freeing a portion of a block is not allowed; the whole block must be freed. However,the realloc function can make a dynamically allocated chunk of memory smaller,effectively freeing the end of it.

释放一块内存的一部分是不允许的。动态分配的内存必须整块一起释放。但是, realloc 函数可以缩小一块动态分配的内存,有效地释放它尾部的部分内存。


Finally, you must be careful not to access memory that has been freeʹd. This warning may seem obvious, but there is a subtle problem here after all. Suppose copies are made of the pointer to a dynamically allocated block, and these copies are sent off to many different parts of the program. It is difficult to make sure that none of these other areas in the program use their copies of the pointer after the memory has been freed. Conversely, you must be sure that all parts of the program are finished using a chunk of memory before freeing it.

最后,你必须小心在意,不要访问已经被free 函数释放了的内存。这个警告看上去很显然,但这里仍然存在一个很微妙的问题。假定你对一个指向动态分配的内存的指针进行了复制,而且这个指针的几份拷贝散布于程序各处。你无法保证当你使用其中一个指针时它所指向的内存是不是已被另一个指针释放。另一方面,你必须确保程序中所有使用这块内存的地方在这块内存被释放之前停止对它的使用。

上一章 Pointers on C——11 Dynamic Memory Allocation.2

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 有蛀牙怎么办可以变好么 拔智齿没拔干净怎么办 蛀牙只剩牙根了怎么办 牙掉的就剩牙根怎么办 蛀牙牙冠都掉了怎么办 拔智齿断了牙根怎么办 牙肉肿痛有脓包怎么办 种植牙到寿命后怎么办 牙齿松动快掉了怎么办 一颗牙齿松动了怎么办 种植牙牙冠掉了怎么办 牙就剩下牙根了怎么办 后面的大牙掉了怎么办 两边大牙都没了怎么办 拔牙把牙根断了怎么办 拔乳牙牙根断了怎么办 拔牙时牙根断了怎么办 孕晚期牙根掉了怎么办 根管治疗后牙裂怎么办 智齿拔断了牙根怎么办 大牙断了牙根还在怎么办 孕妇牙疼的要命怎么办 牙烂了个大窟窿怎么办 牙齿又痒又痛怎么办 大牙就剩牙根了怎么办 蛀牙只剩牙根痛怎么办 带牙冠的牙疼了怎么办 牙龈肉与牙分离怎么办 后槽牙松动还疼怎么办 嘴唇又干又痒怎么办 嘴唇边突然肿了怎么办 大牙齿蛀牙很疼怎么办 蛀牙经常牙疼怎么办呢 小孩牙齿稀疏牙缝大怎么办 7岁牙齿缝隙大怎么办 小孩牙掉了不长怎么办 牙掉了一年不长怎么办 27岁了牙齿不齐怎么办 整个牙床都在痛怎么办 牙神经漏出来了怎么办 孕9个多月牙齿痛怎么办