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
- Pointers on C——11 Dynamic Memory Allocation.3
- Pointers on C——11 Dynamic Memory Allocation.1
- Pointers on C——11 Dynamic Memory Allocation.2
- Pointers on C——11 Dynamic Memory Allocation.4
- Pointers on C——11 Dynamic Memory Allocation.5
- Pointers on C——11 Dynamic Memory Allocation.6
- Pointers on C——6 Pointers.11
- Pointers on C——6 Pointers.3
- Dynamic memory allocation example
- Geeksquiz | Dynamic Memory Allocation
- dynamic memory allocation
- dynamic memory allocation
- [转载]Dynamic Memory Allocation and Fragmentation in C and C++
- [Tutorial] DMA Dynamic Memory Allocation
- Pointers on C——6 Pointers.1
- Pointers on C——6 Pointers.2
- Pointers on C——6 Pointers.4
- Pointers on C——6 Pointers.5
- 欢迎使用CSDN-markdown编辑器
- react-native-redux 简易教程
- Two Sum
- python机器学习及实战代码13-16,程序运行时出现提醒及修改
- 中国地理-一些知识的总结
- Pointers on C——11 Dynamic Memory Allocation.3
- JDK下载、安装和环境变量配置
- vm虚拟机安装centos7,配置网卡
- springmvc报400错误,并用@inintBinder解决类型转换问题
- Android AsyncTask源码分析
- Pointers on C——11 Dynamic Memory Allocation.4
- Pointers on C——11 Dynamic Memory Allocation.5
- 从FTP获取PDF文件流并展示到页面
- (CodeForces