内存管理-【2】
来源:互联网 发布:ios9越狱优化 编辑:程序博客网 时间:2024/06/05 10:17
例子1:运行正常
#include <stdio.h>
void Test(void)
{
char*str = NULL;
str = (char *)malloc(sizeof(char) * 100);
strcpy(str,"hello");
printf("%s\n",str);
}
int main()
{
Test();
return0;
}
例子2:运行出错
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"); // 运行错误
}
答:如果直接传递str(值传递),由于编译器对GetMemory()的操作是先将char *str进行一份拷贝例如char *str_copy,因此之后改变的是变量str_copy而不是变量str本身。
原因是编译器总是为每个参数制作临时副本。指针参数p, 其副本为_p,使_p=p。如果改变了_p所指的内容,相应的p所指的内容也跟着改变(毕竟指向同样的地方)。但是在GetMemory中动态分配内存空间,改变了_p的内容。在调用函数中的p还是指向NULL。再者,因为函数GetMemory中动态分配了空间,但是没释放,这样调用一次函数,就泄露了一次内存。图示:
例子3:修改2之后运行正常
voidGetMemory2(char **p, int num)
{
*p = (char *)malloc(sizeof(char) * num);
}
voidTest2(void)
{
char *str = NULL;
GetMemory2(&str,100); // 注意参数是&str,而不是str
strcpy(str, "hello");
cout<< str << endl;
free(str);
}
传递相当于char **p,函数拷贝相当是char **_p,将_p所指向的值变了则原来p所指向的值也就变了,原理是一样的,比较难理解,图示表示:
例子4:更好的解决办法
char *GetMemory(int num)
{
char *p = (char *)malloc(sizeof(char) * num);
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory(100); //str指向了动态分配的空间
strcpy(str, "hello");
free(str)
}
例子5:下面违反函数设计的基本原则
char *GetString()
{
char *p = "hello world"; //数组内容存储在字符常量区,函数结束时,不会释放掉
return p;
}
void Test(void)
{
char *str = NULL;
str = GetString();
cout << str << endl;
}
- Linux内存管理(2)
- 内存管理[2]
- C++内存管理(2)
- 内存管理2
- 内存管理2get_vm_area
- 内存管理2
- iphone 内存管理2
- 内存管理(2)
- 2、OC内存管理
- 内存管理-【2】
- C++内存管理2
- 九---内存管理2
- 内存管理(2)
- 2、OC内存管理
- 内存管理(2)
- Linux内存管理(2):内存描述
- 2 时间管理和内存管理
- 内存管理(2)系统空间的内存管理算法
- 实现三个div并排,中间的div自适应屏幕的问题
- ZLL记录
- 程序中访问空指针为什么会出错?
- windows下Oracle数据库冷备份操作[整理]
- java实现的MySQL自动备份和还原(struts2+Hibernate)---兼容 window+Linux
- 内存管理-【2】
- hdu - 2955 - Robberies
- ASP环境下轻松实现报表的打印 (转)
- 弟子规(一)
- Android中Bitmap和Drawable
- mybait
- C# 读取DataTable使用Reader方式
- JAVA中的接口interface
- 【Linux学习】Linux 系统结构