【c++】指针参数是如何传递内存的

简介:

参数策略

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

复制代码
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;
 }
复制代码

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




本文转自jihite博客园博客,原文链接:http://www.cnblogs.com/kaituorensheng/p/3246900.html,如需转载请自行联系原作者

相关文章
|
2月前
|
存储 程序员 编译器
玩转C++内存管理:从新手到高手的必备指南
C++中的内存管理是编写高效、可靠程序的关键所在。C++不仅继承了C语言的内存管理方式,还增加了面向对象的内存分配机制,使得内存管理既有灵活性,也更加复杂。学习内存管理不仅有助于提升程序效率,还有助于理解计算机的工作原理和资源分配策略。
|
1月前
|
存储 Linux C语言
C++/C的内存管理
本文主要讲解C++/C中的程序区域划分与内存管理方式。首先介绍程序区域,包括栈(存储局部变量等,向下增长)、堆(动态内存分配,向上分配)、数据段(存储静态和全局变量)及代码段(存放可执行代码)。接着探讨C++内存管理,new/delete操作符相比C语言的malloc/free更强大,支持对象构造与析构。还深入解析了new/delete的实现原理、定位new表达式以及二者与malloc/free的区别。最后附上一句鸡汤激励大家行动缓解焦虑。
|
1月前
|
SQL Oracle 关系型数据库
【YashanDB知识库】崖山有哪些内存参数,Share Pool各个参数之间有什么关系
【YashanDB知识库】崖山有哪些内存参数,Share Pool各个参数之间有什么关系
【YashanDB知识库】崖山有哪些内存参数,Share Pool各个参数之间有什么关系
|
4月前
|
存储 缓存 编译器
【硬核】C++11并发:内存模型和原子类型
本文从C++11并发编程中的关键概念——内存模型与原子类型入手,结合详尽的代码示例,抽丝剥茧地介绍了如何实现无锁化并发的性能优化。
245 68
|
2月前
|
SQL Oracle 关系型数据库
【YashanDB 知识库】崖山有哪些内存参数,Share Pool 各个参数之间有什么关系
在使用YashanDB时,用户常对内存参数配置有疑问,尤其是23.2及以上版本中,如SQL_POOL_SIZE+DICTIONARY_CACHE_SIZE超100报错,影响跑批性能。主要内存参数包括SHARE_POOL_SIZE、SQL_POOL_SIZE、DICTIONARY_CACHE_SIZE等,需合理配置以优化性能。SHARE POOL内含多个POOL,可动态调整。具体配置方法及观察使用情况的方式详见官网文档。
|
2月前
|
安全 C语言 C++
彻底摘明白 C++ 的动态内存分配原理
大家好,我是V哥。C++的动态内存分配允许程序在运行时请求和释放内存,主要通过`new`/`delete`(用于对象)及`malloc`/`calloc`/`realloc`/`free`(继承自C语言)实现。`new`分配并初始化对象内存,`delete`释放并调用析构函数;而`malloc`等函数仅处理裸内存,不涉及构造与析构。掌握这些可有效管理内存,避免泄漏和悬空指针问题。智能指针如`std::unique_ptr`和`std::shared_ptr`能自动管理内存,确保异常安全。关注威哥爱编程,了解更多全栈开发技巧。 先赞再看后评论,腰缠万贯财进门。
162 0
|
3月前
|
存储 程序员 编译器
什么是内存泄漏?C++中如何检测和解决?
大家好,我是V哥。内存泄露是编程中的常见问题,可能导致程序崩溃。特别是在金三银四跳槽季,面试官常问此问题。本文将探讨内存泄露的定义、危害、检测方法及解决策略,帮助你掌握这一关键知识点。通过学习如何正确管理内存、使用智能指针和RAII原则,避免内存泄露,提升代码健壮性。同时,了解常见的内存泄露场景,如忘记释放内存、异常处理不当等,确保在面试中不被秒杀。最后,预祝大家新的一年工作顺利,涨薪多多!关注威哥爱编程,一起成为更好的程序员。
114 0
|
4月前
|
存储 程序员 C++
深入解析C++中的函数指针与`typedef`的妙用
本文深入解析了C++中的函数指针及其与`typedef`的结合使用。通过图示和代码示例,详细介绍了函数指针的基本概念、声明和使用方法,并展示了如何利用`typedef`简化复杂的函数指针声明,提升代码的可读性和可维护性。
160 1
|
5月前
|
存储 C语言
C语言如何使用结构体和指针来操作动态分配的内存
在C语言中,通过定义结构体并使用指向该结构体的指针,可以对动态分配的内存进行操作。首先利用 `malloc` 或 `calloc` 分配内存,然后通过指针访问和修改结构体成员,最后用 `free` 释放内存,实现资源的有效管理。
491 13
|
5月前
|
存储 C语言 开发者
C 语言指针与内存管理
C语言中的指针与内存管理是编程的核心概念。指针用于存储变量的内存地址,实现数据的间接访问和操作;内存管理涉及动态分配(如malloc、free函数)和释放内存,确保程序高效运行并避免内存泄漏。掌握这两者对于编写高质量的C语言程序至关重要。
166 11
下一篇
oss创建bucket