参数策略ios
若是函数的参数是一个指针,不要期望用该指针去动态申请内存。以下:数组
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"); //运行错误 }
缘由是编译器老是为每一个参数制做临时副本。指针参数p, 其副本为_p,使_p=p。若是改变了_p所指的内容,相应的p所指的内容也跟着改变(毕竟指向一样的地方)。可是在GetMemory中动态分配内存空间,改变了_p的内容。在调用函数中的p仍是指向NULL。再者,由于函数GetMemory中动态分配了空间,可是没释放,这样调用一次函数,就泄露了一次内存。图示:函数
若是非得用指针参数申请内存,能够用指针的指针做为参数申请内存spa
void GetMemory(char **p, int num) { *p = (char *)malloc(sizeof(char) * num); } void Test(void) { char *str = NULL; GetMemory(&str, 100); //记得加地址符
strcpy(str, "hello");
free(str) }
原理是同样的,比较难理解,图示表示:指针
比较好的方法是传指针的引用code
#include <iostream> #include <string> #include <cstring> #include <cstdlib> using namespace std; void GetMemory(char *&p, int num) { p = (char *)malloc(sizeof(char) * num); } void Test(void) { char *str = NULL; GetMemory(str, 100); strcpy(str, "hello"); cout << str << endl; free(str); } int main() { Test(); }
这里注意指针的引用 为char* &a,要是很差理解能够这样:blog
typedef char* pchar; pchar &a
返回值策略内存
能够用函数返回值来传递动态内存。这中方法比“指针的指针”简单多了编译器
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) }
在使用返回值时,千万别返回指向“栈内存”的指针、引用,由于该内存在函数结束时自动消亡了,返回的指针是个野指针了。例如string
char *GetString() { char p[] = "hello world"; //数组内容存储在栈区,函数结束时,会释放掉 return p; } void Test(void) { char *str = NULL; str = GetString(); //由于非配的内存早已释放掉,此时的str是个野指针,内容是垃圾 cout << str << endl; }
在函数中不定义数组,定义指针,示例:
char *GetString() { char *p = "hello world"; //数组内容存储在静态区,函数结束时,不会释放掉 return p; } void Test(void) { char *str = NULL; str = GetString(); cout << str << endl; }
此时的程序是正确的,可是有一点,此时分配的内存处于静态区,是只能够读取可是不能够修改的。