参数策略

如果函数的参数是一个指针,不要指望用该指针去动态申请内存。如下:

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中动态分配了空间,但是没释放,这样调用一次函数,就泄露了一次内存。图示:

如果非得用指针参数申请内存,可以用指针的指针作为参数申请内存

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)
}

原理是一样的,比较难理解,图示表示:

比较好的方法是传指针的引用

#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,要是不好理解可以这样:

    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)
}

在使用返回值时,千万别返回指向“栈内存”的指针、引用,因为该内存在函数结束时自动消亡了,返回的指针是个野指针了。例如

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;
}

此时的程序是正确的,但是有一点,此时分配的内存处于静态区,是只可以读取但是不可以修改的。

最新文章

  1. Software Project Management hw1
  2. 【C语言】汉诺塔问题
  3. iOS视频直播初窥:高仿&lt;喵播APP&gt;
  4. 顺序表及其多种实现方式 --- C/C++
  5. 第十一章、认识与学习 BASH 管线命令 (pipe)
  6. [LeetCode] Word Break II 解题思路
  7. ASP.NET-FineUI开发实践-4
  8. ArcGIS API for JavaScript 4.2学习笔记[20] 使用参数查询要素(油井和地震关系)
  9. Linux--线程安全与可重入函数的异同
  10. MySQL (五)
  11. python SMTP 发送邮件 阿里企业邮箱、163邮箱 及535错误
  12. android 开发 View _7_ 动态自定义View
  13. Unity AssetBundle打包资源工具
  14. AtCoder Grand Contest 018 E Sightseeing Plan
  15. 8.2.1.3 Range 优化
  16. .net 中使用oracle 的sql 语句
  17. 【sping揭秘】12、SpringAOP的实现机制
  18. 【转载】SQL注入原理讲解
  19. SQL Server 查询请求
  20. 利用signapk.jar工具对apk文件进行签名

热门文章

  1. cookie和Session是啥?
  2. Lighting Techinology of the Last Of Us (2013 SIGGRAPH)
  3. Peter Shirley Ray Tracing in One Weekend(上篇)
  4. Java中的集合List、ArrayList、Vector、Stack(三)
  5. winform中的Windows Media Player播放器设置
  6. Java项目出现的问题01----学习
  7. 查看PublicKeyToken和生成PublicKeyToken
  8. java实现上传文件夹
  9. jQuery系列(六):jQuery的文档操作
  10. php-m 与 phpinfo 不一致的解决办法