经典C++题目Getmomory函数

深入理解c++代码与内存的交互过程

demo1:

void GetMemory(char* p)
{
    p = (char*)malloc(100);
}

int main()
{
    char* pstr = NULL;
    GetMemory(pstr);
    strcpy_s(pstr, sizeof("hello world"), "hello world");
    std::cout << pstr << std::endl;
}

结果:运行此程序会产生崩溃,和内存泄漏。

分析:

void GetMemory(char* p)
{ 
    p = (char*)malloc(100);
    std::cout << "p的地址:" << &p << std::endl;
}

int main()
{
    char* pstr = NULL;
    std::cout <<"pstr的地址:" << &pstr << std::endl;
    GetMemory(pstr);
    strcpy_s(pstr, sizeof("hello world"), "hello world");
    std::cout << pstr << std::endl;
}

//输出结果
pstr的地址:00000039474FFA18
p的地址:00000039474FF9F0

char* pstr 定义了一个指针变量,pstr的地址是00000039474FFA18,里面存储的值为NULL

GetMemory(pstr),把pstr的副本拷贝一份传入GetMemory的栈空间,pstr和p指向的是同一个空间。但这是两个不同的变量。

 p = (char*)malloc(100); 给p创建一个100个字节大小的空间,但不会影响pstr.

GetMemory函数结束。p变量释放。分配的堆空间不会释放。

返回到main函数中,pstr还是指向NULL,此时执行strcpy_s就会报错。

解决办法1:使用二级指针,把二级指针传递进去,二级指针指向的值就和pstr是一样,在实际项目开发中二级指针也经常能看到,它的一个功能就是这种作用,用来改变一级指针的值

void GetMemory(char** p)
{ 
    *p = (char*)malloc(100);
    std::cout << "p的地址:" << &p << std::endl;
}

int main()
{
    char* pstr = NULL;
    std::cout <<"pstr的地址:" << &pstr << std::endl;
    GetMemory(&pstr);
    strcpy_s(pstr, sizeof("hello world"), "hello world");
    std::cout << pstr << std::endl;
}
//输出结果
pstr的地址:000000F63F30FB18
p的地址:000000F63F30FAF0
hello world

解决方法二:修改返回值的类型

char* GetMemory(char* p)
{ 
    p = (char*)malloc(100);
    std::cout << "p的地址:" << &p << std::endl;
    return p;
}

int main()
{
    char* pstr = NULL;
    std::cout <<"pstr的地址:" << &pstr << std::endl;
   pstr =  GetMemory(pstr);
    strcpy_s(pstr, sizeof("hello world"), "hello world");
    free(pstr);
    std::cout << pstr << std::endl;
}
//结果
pstr的地址:000000041113F988
p的地址:000000041113F960
hello world

demo2:

char* GetMemory2(void)
{
    char p[] = "hello world";
    return p;
}


int main()
{
    char* str = NULL;
    str = GetMemory2();
    std::cout << str << std::endl;
}

结果:会输出乱码

分析:Getmomory2函数里面,p是个临时变量,函数运行结束后,存在于函数栈空间的变量p里面的内容就会释放掉。和demo1进行比较,在demo1里面有个解决方法二就是return回去能解决demo1的问题,但是为啥不能解决demo1的问题,两者一个是改变指针的值,一个是改变指针指向的内容。执行完GetMemory2() 后str变量 和函数变量的副本指向同一个地方,但是Getmomory执行完后,里面的值已经释放掉了,所以str指向的是已经释放掉的内存,所以是乱码。

Demo3:

void GetMemory3(char** p, int num)
{
    *p = (char*)malloc(num);
}

int main()
{
    char* str = NULL;
    GetMemory3(&str, 100);
    strcpy_s(str,sizeof("hello"),"hello");
    std::cout << str << std::endl;
}

结果:能正确输出 hello.但是会产生内存泄漏,要free掉

总结:如果函数是传指针,则函数能改变指针指向的值,不能改变指针本身的值,如果是需要改变指针本身,则要用双指针。

Demo4:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值