返回首页
当前位置: 主页 > 编程语言 > C/C++教程 >

c语言 内存和指针

时间:2015-05-08 23:05来源:电脑教程学习网 www.etwiki.cn 编辑:admin

内存管理
常见的内存错误及其对策
*内存未分配成功却使用了它:
在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查 ;如果使用malloc或者new来申请内存,应该用if(p==NULL)或if(p!=NULL)进防错处理。
*无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。
*内存分配成并且已经初始化,但操作越过了内存的边界。
*内存泄露。动态内存的申请与释放必须配对,申请与释放的次数一定要相同。
*释放了内存却继续使用它(三种情况):
(1)对象调用关系过于复杂。应重新设计数据结构,解决对象管理混乱局面
(2)函数注意不要返回指向“栈内存”的“指针”或者“引用”,该内存在函数体结束时会被销毁
(3)使用free或delete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。
7.3指针与数组的对比
*数组要么在静态存储区被创建(如全局数组),要么在栈上被创建。数组名对应着(而不是指向)一块内存,其地址与容量在声明周期内保持不变,只有数组的内容可以改变。
7.3.1修改内容
企图修改常量字符串的内容导致运行错误。
7.3.2内容复制与比较
对数组进行复制:strcpy();
对数组进行比较:strcmp();
//指针
int len=strlen(a);
char *p=(char *)malloc(sizeof(char)*(len+1));
strcpy(p,a); //不要用p=a,
if(strcmp(p,a)==0) //不要用if(p==a),那是比较地址
7.3.3计算内存容量
char a[]="hello world"; //sizeof(a)的值为12(别忘了'\0')。
void Func(char a[100])
{
cout<<sizeof(a)<<endl;//4字节而不是100字节,当数组作为函数的参数进行传递时,该数组自动退化
//为同类型的指针。
}
7.4指针参数是如何传递内存的?
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。
void GetMemory(char *p,int num)
{
p=(char *)malloc(sizeof(char)*num);
}
void Test(void)
{
char *str=NULL;
GetMemory(str,100);//str仍然为NULL
strcpy(str,"hello"); //运行错误
}
Test函数的语句GetMemory(str,200)并没有使str获得期望的内存,str依旧是NULL。
毛病出在GetMemory()中。编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p=p。如果函数体内的程序修改了_p的内容,就导致参数p的内容作相应的修改。这就是指针可以用作输出参数的原因。在上面代码中,_p申请了新的内存,只是把_p所指的内存地址改变了,但是p丝毫未变。所以函数GetMemory()并不能输出任何东西。事实上,每执行一次GetMemory()就会泄露一块内存,因为没有用free释放内存。
如果非要用指针参数去申请内存,那么应该改用"指向针针的指针"
void GetMemory2(char **p,int num)
{
*p=(char *)malloc(sizeof(char)*num);
}
void Test2(void)
{
char *str=NULL;
GetMemory(&str,100);//注意参数是&str
strcpy(str,"hello");
cout<<str<<endl;
free(str);
}
还可以用函数返回值来传递动态内存,这种方法更简单。
char * GetMemory3(int num)
{
char *p=(char*)malloc(sizeof(char)*num);
return p;
}
void Test3(void)
{
char *str=NULL;
str=GetMemory3(100);
strcpy(str,"hello");
cout<<str<<endl;
free(str);
}
用函数返回值传递动态内存这种方法虽然好用,但是要注意不要用return语句返回指向“栈内存"的指针,因为该内存在函数结束时自动消亡。
char *GetString(void)
{
char p[]="hello world";
return p; //编译器将提出警告
}
void Test4(void)
{
char *str=NULL;
str=GetString();//str的内容是垃圾,GetString()中的p指向的内存已经被释放
cout<<str<<endl;
}
改为下面的代码:
char *GetString2(void)
{
char *p="hello world";
return p;
}
void Test5(void)
{
char *str=NULL;
str=GetString2();
cout<<str<<endl;
}

顶一下
(1)
100%
踩一下
(0)
0%
标签(Tag):C语言
------分隔线----------------------------
------分隔线----------------------------
发表评论
请自觉遵守互联网相关的政策法规,严禁发布色情、暴力、反动的言论。
评价:
表情:
验证码:点击我更换图片
推荐内容