一.内存资源被free后,不要对其进行读写操作。
当内存被释放,其内容可能会保持不变和可访问。若访问其内容可能发生意想不到的变化,导致意想不到的程序行为。因此,有必要保证内存一旦释放,就不能写入或读取。
错误代码:
-
for(p = head; p != NULL; p = p->next) {
-
free(p);
-
}
在执行p=p->next前,p已经被free。
正确代码:
-
for (p = head; p != NULL; p = q) {
-
q = p->next;
-
free(p);
-
}
二,只释放同一内存资源一次,避免double-free的问题。
错误代码:
-
x = malloc (number * sizeof(int));
-
if (x == NULL) {
-
/* Handle Allocation Error */
-
}
-
/* ... */
-
if (error_conditon == 1) {
-
/* Handle Error Condition*/
-
free(x);
-
}
-
/* ... */
-
free(x)
正确代码:
-
if (sizeof(int) > SIZE_MAX/number) {
-
/* handle overflow */
-
}
-
x = malloc(number * sizeof(int));
-
if (x == NULL) {
-
/* Handle Allocation Error */
-
}
-
/* ... */
-
if (error_conditon == 1) {
-
/* Handle Error Condition*/
-
}
-
/* ... */
-
free(x)
三.有必要检查内存管理函数返回的状态并适当地处理错误
错误代码:
-
/* ... */
-
p = realloc(p, new_size);
-
if (p == NULL) {
-
/* Handle Error */
-
}
-
/* ... */
若realloc函数失败,p指针指向NULL,原始的内存区域则会没有释放而造成内存泄漏。
正确代码:
-
/* ... */
-
q = realloc(p, new_size);
-
if (q == NULL) {
-
/* Handle Error */
-
}
-
p = q;
-
/* ... */
四.free函数只能释放动态分配的内存资源
若free的内存不是动态配分的,会导致程序异常中断或其他错误(依赖于编译器)。
错误代码:
-
#define MAX_ALLOCATION 1000
-
int main(int argc, char *argv[]) {
-
char *str = NULL;
-
size_t len;
-
if (argc == 2) {
-
len = strlen(argv[1])+1;
-
if (len > MAX_ALLOCATION) {
-
/* Handle Error */
-
}
-
str = malloc(len);
-
if (str == NULL) {
-
/* Handle Allocation Error */
-
}
-
strcpy(str, argv[1]);
-
}
-
else {
-
str = "usage: $>a.exe [string]";
-
printf("%s\n", str);
-
}
-
/* ... */
-
free(str);
-
return 0;
-
}
若代码执行到17行后,str指向字符串常量,这里是str是不允许被free来释放的,会产生错误。
正确代码:
-
#define MAX_ALLOCATION 1000
-
int main(int argc, char *argv[]) {
-
char *str = NULL;
-
size_t len;
-
if (argc == 2) {
-
len = strlen(argv[1])+1;
-
if (len > MAX_ALLOCATION) {
-
/* Handle Error */
-
}
-
str = malloc(len);
-
if (str == NULL) {
-
/* Handle Allocation Error */
-
}
-
strcpy(str, argv[1]);
-
}
-
else {
-
printf("%s\n", "usage: $>a.exe [string]");
-
return -1;
-
}
-
/* ... */
-
free(str);
-
return 0;
-
}
五.为对象申请足够大的内存
malloc、calloc、realloc函数的size参数必须是有晓且能够容纳对象。若size大小不对或被恶意修改,会导致缓冲溢出。不正确的尺寸参数,检查范围不足,整数溢出,或截断可能导致缓冲区分配的大小不足。
错误代码:
-
void function(size_t len) {
-
long *p;
-
if (len > SIZE_MAX / sizeof(long)) {
-
/* handle overflow */
-
}
-
p = malloc(len * sizeof(int));
-
if (p == NULL) {
-
/* handle error */
-
}
-
/* ... */
-
free(p);
-
}
若sizeof(long)大于sizeof(int), malloc(len*sizeof(int))分配的内存资源就会不够大。
正确代码:
-
void function(size_t len) {
-
long *p;
-
if (len > SIZE_MAX / sizeof(long)) {
-
/* handle overflow */
-
}
-
p = malloc(len * sizeof(long));
-
if (p == NULL) {
-
/* handle error */
-
}
-
/* ... */
-
free(p);
-
}
阅读(1086) | 评论(0) | 转发(0) |