春节小练习——动态内存的传递
2018-02-19 09:51
190 查看
例1:
copyName()函数中用new分配了堆内存。其内存大小为传入的字符串长度,这里有个bug。由于字符串是以\0作为结束符的,应该多分配一个字节存放\0;否则将修改后面的内存的值,造成无法预料的严重后果;
修改为:char *newname = new char [strlen(name) + 1];
例2:
copyName()函数中,返回其内数组的地址,由于数组处于栈中,当copyName调用结束后,栈就会被销毁。这里应该返回堆内存地址。
修改为:char *newname = new char [strlen(name) + 1];
内存泄漏
这里的GetMemory函数有问题。GetMemory函数体内的p实际上是main函数中的str变量在GetMemory函数栈中的一个备份,因为编译器总是为函数的每个参数制作临时的变量。因此,虽然在在函数体中p申请了堆内存,但是返回到main函数时,str还是NULL,并不指向那块内存,调用strcpy时会导致程序崩溃。
实际上,GetMemory并不能做任何有用的事情。这里还要注意,由于从GetMemory函数返回时不能获得堆中内存的地址,那块堆内存就不能被继续引用,也就得不到释放。因此调用一次GetMemory函数就会产生num字节的内存泄漏。
3种方法解决上面的动态内存不能传递的问题
1、在C语言中,可以通过采用指向指针的指针解决这个问题,可以把str的地址传给函数GetMemory。
2、在C++中,多了一种选择,就是传递str指针的引用。
3、使用函数返回值来传递动态内存。
char *copyName(char *name) { char *newname = new char[strlen(name)]; strcpy(newname, name); return newname; } int main() { printf("%s\n", copyName("test")); return 0; }
copyName()函数中用new分配了堆内存。其内存大小为传入的字符串长度,这里有个bug。由于字符串是以\0作为结束符的,应该多分配一个字节存放\0;否则将修改后面的内存的值,造成无法预料的严重后果;
修改为:char *newname = new char [strlen(name) + 1];
例2:
char *copyName(char *name) { char newname[20] = ""; strcpy(newname, name); return newname; } int main() { printf("%s\n", copyName("test")); return 0; }
copyName()函数中,返回其内数组的地址,由于数组处于栈中,当copyName调用结束后,栈就会被销毁。这里应该返回堆内存地址。
修改为:char *newname = new char [strlen(name) + 1];
内存泄漏
void GetMemory(char *p, int num) { p = (char *)malloc(sizeof(char) * num); } int main() { char *str = NULL; GetMemory(str, 10); strcpy(str, "hello"); return 0; }
这里的GetMemory函数有问题。GetMemory函数体内的p实际上是main函数中的str变量在GetMemory函数栈中的一个备份,因为编译器总是为函数的每个参数制作临时的变量。因此,虽然在在函数体中p申请了堆内存,但是返回到main函数时,str还是NULL,并不指向那块内存,调用strcpy时会导致程序崩溃。
实际上,GetMemory并不能做任何有用的事情。这里还要注意,由于从GetMemory函数返回时不能获得堆中内存的地址,那块堆内存就不能被继续引用,也就得不到释放。因此调用一次GetMemory函数就会产生num字节的内存泄漏。
3种方法解决上面的动态内存不能传递的问题
1、在C语言中,可以通过采用指向指针的指针解决这个问题,可以把str的地址传给函数GetMemory。
2、在C++中,多了一种选择,就是传递str指针的引用。
3、使用函数返回值来传递动态内存。
#include <iostream> using namespace std; void GetMemory1(char *p, int num)//错误,内存泄漏 { p = (char *)malloc(sizeof(char) * num); } void GetMemory2(char **p, int num)//正确,二级指针 { *p = (char *)malloc(sizeof(char) * num); } void GetMemory3(char* &p, int num)//正确,传引用 { p = (char *)malloc(sizeof(char) * num); } char *GetMemory4(int num)//正确,函数返回值 { char *p = (char *)malloc(sizeof(char) * num); return p; } int main() { char *str1 = NULL; char *str2 = NULL; char *str3 = NULL; char *str4 = NULL; //GetMemory1(str1, 20); GetMemory2(&str2, 20); GetMemory3(str3, 20); str4 = GetMemory4(20); strcpy(str2, "GetMemory 2"); strcpy(str3, "GetMemory 3"); strcpy(str4, "GetMemory 4"); cout << "str2:" << str2 << endl; cout << "str3:" << str3 << endl; cout << "str4:" << str4 << endl; //每当决定不再使用堆内存时,应该释放堆内存 free(str2); free(str3); free(str4); //并把堆内存置空 str2 = NULL; str3 = NULL; str4 = NULL; return 0; }
相关文章推荐
- 传递动态内存
- 春节送礼,传递“互动能量”暖人心
- C/C++ 传递动态内存
- 传递动态内存
- 解决动态内存传递不能传递的3种方法
- 练习3:参数值传递的汇编实质
- 函数:函数操作结构体通过按值传递以及按址传递,使用动态内存
- [消息传递之五]-NSMatchPort练习
- 面试---传递动态内存
- 【基础练习】【传递闭包】codevs1506 传话题解
- 安卓小日记练习(6)listview点击后的界面布局和数据传递的完善
- 对象在方法中进行连续的传递 —— 士兵开枪练习
- java读书笔记:练习对象引用传递
- 指针-传递动态内存
- Extjs练习——服务器端获取信息填充客户端表单,注意Radio以及Checkbox值的传递
- 动态内存的传递
- C++Primer 动态内存练习 12.6题
- C/C++ 高质量编程--动态内存传递疑问解析 1
- 类型的转换和多分支语句(函数之间数据的传递)小练习
- C/C++ 传递动态内存