GetMemory()的四道经典问题

阅读推荐

阅读此篇前可以先阅读:指针变量的传值和传址

GetMemory()的四道经典问题

问题一:malloc 不能返回动态内存

请问运行main 函数会有什么样的结果?

#include <stdio.h>
#include <stdlib.h>
void getmemory(char *p)
{
  p=(char *) malloc(100);
  strcpy(p,"hello world");
}
int main( )
{
  char *str=NULL;
  getmemory(str);
  printf("%s/n",str);
  free(str);
  return 0;
}

运行结果:程序崩溃,getmemory中的malloc 不能返回动态内存, free()对str操作很危险。

当参数是指针时容易忽略,请不要用值传递(这样会导致str没有指向分配到的内存),C语言中可以用指针传。

C语言中,没有reference(引用)的概念。这是C规范中规定,之所以大家会认为C语言会有引用,是因为在cpp文件中,支持以c形式写代码。因而导致大家误认为c支持引用。并且很多编译器C/C++是共用的C中有C++代码也能过,有时候C和C++的界限不是很清晰。

C语言是值传递,故在函数调用中修改的值,并不会返传至主调函数。所以原程序在getmemory函数中malloc获得的地址空间的首地址的值只在函数内部有效,函数调用结束后该值就丢失了,传值是把实参的值拷贝给形参,运算中是对形参进行操作,实参的值在运算中不会发生变化。传址是把实参的地址传给形参,运算中是对实参进行操作,会改变实参的值

所以如果考虑使用引用的话,要在函数里返回内存有三种办法:

  • 使用指针的指针 **p ,用这个指针指向一个需要分配内存的值。
  • 还可以在函数里创造一个指针然后,return他就可以了,这种方法更简单。
  • 传引用

正确写法:

#include <stdio.h> 
#include <stdlib.h> 
void getmemory(char **p) 
{ 
  *p=(char *) malloc(100); 
  strcpy(*p,"hello world"); 
} 
int main() 
{ 
  char *str=NULL; 
  getmemory(&str); 
  printf("%s/n",str); 
  free(str); 
  return 0; 
} 
//传引用
void getmemory(char &*p) 
{ 
    p=(char *) malloc(100); strcpy(p,"hello world"); 
} 
//传址
void getmemory(char **p) 
{ 
    *p=(char *)malloc(100); strcpy(*p,"hello world"); 
}

问题二:GetMemory返回的是指向“栈内存”的指针

请问运行Test 函数会有什么样的结果?

char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}

分析:可能是乱码。因为GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原来的内容已经被清除,新内容不可知。

问题三:内存泄漏

请问运行Test 函数会有什么样的结果?

void GetMemory(char **p, int num)
{
*p = (char *)malloc(num);
}
void Test(void)
{
char *str = NULL;
GetMemory(&str, 100);
strcpy(str, "hello");
printf(str);
}

分析:
(1)能够输出hello
(2)内存使用完没有及时通过free释放,造成内存泄漏

关于内存溢出与内存泄漏

  • 内存泄漏是指程序在申请内存后,无法释放已申请的内存空间。
  • 内存溢出是指程序申请内存时,没有足够的内存供申请者使用;或者说提供一块存储int数据的存储空间,但存储了long数据,则结果是内存不够用,报错OOM。
  • 内存泄漏的堆积最终会导致内存溢出

问题四:篡改动态内存区的内容

请问运行Test 函数会有什么样的结果?

void Test(void)
{
    char *str = (char *) malloc(100);
    strcpy(str, “hello”);
    free(str);
    if(str != NULL)
    {
      strcpy(str, “world”);
      printf(str);
    }
}

分析:
篡改动态内存区的内容,后果难以预料,非常危险。因为free(str);之后,str 成为野指针,if(str != NULL)语句不起作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一只嵌入式爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值