您的位置:首页 > 其它

常见的内存错误【四】

2006-11-27 20:40 375 查看
9. 分配/释放不配对

大家都知道malloc要和free配对使用,new要和delete/delete[]配对使用,重载了类new操作,应该同时重载类的delete/delete[]操作。这些都是书上反复强调过的,除非当时晕了头,一般不会犯这样的低级错误。
而有时候我们却被蒙在鼓里,两个代码看起来都是调用的free函数,实际上却调用了不同的实现。比如在Win32下,调试版与发布版,单线程与多线程是不同的运行时库,不同的运行时库使用的是不同的内存管理器。一不小心链接错了库,那你就麻烦了。程序可能动则崩溃,原因在于在一个内存管理器中分配的内存,在另外一个内存管理器中释放时出现了问题。

10. 返回指向临时变量的指针

大家都知道,栈里面的变量都是临时的。当前函数执行完成时,相关的临时变量和参数都被清除了。不能把指向这些临时变量的指针返回给调用者,这样的指针指向的数据是随机的,会给程序造成不可预料的后果。
下面是个错误的例子:

char* get_str(void)
{
char str[] = {"abcd"};
return str;
}

int main(int argc, char* argv[])
{
char* p = get_str();
printf("%s/n", p);
return 0;
}

下面这个例子没有问题,大家知道为什么吗?

char* get_str(void)
{
char* str = {"abcd"};
return str;
}
int main(int argc, char* argv[])
{
char* p = get_str();
printf("%s/n", p);
return 0;
}

11. 试图修改常量

在函数参数前加上const修饰符,只是给编译器做类型检查用的,编译器禁止修改这样的变量。但这并不是强制的,你完全可以用强制类型转换绕过去,一般也不会出什么错。
而全局常量和字符串,用强制类型转换绕过去,运行时仍然会出错。原因在于它们是是放在常量区里面的,而常量区内存页面是不能修改的。试图对它们修改,会引发内存错误。
下面这个程序在运行时会出错:

int main(int argc, char* argv[])
{
char* p = "abcd";
*p = '1';
return 0;
}

12. 误解传值与传引用

在C/C++中,参数默认传递方式是传值的,即在参数入栈时被拷贝一份。在函数里修改这些参数,不会影响外面的调用者。如:

#include <stdlib.h>
#include <stdio.h>

void get_str(char* p)
{
p = malloc(sizeof("abcd"));
strcpy(p, "abcd");
return;
}

int main(int argc, char* argv[])
{
char* p = NULL;
get_str(p);
printf("p=%p/n", p);
return 0;
}

在main函数里,p的值仍然是空值。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: