内存管理几个程序实例

一、Test 函数的语句 GetMemory(str, 200)并没有使 str 获得期望的内存, str 依旧是 NULL,为什么?

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"); // 运行错误
}

解析: GetMemory(str, 100) 传的是str的值(NULL),所以分配内存的时候是对str值操作,不是对它的地址的操作。所以strcpy调用时,str值仍为NULL,并未malloc到内存。malloc后一定要free,否则会造成内存泄漏(退出后程序仍占用内存,可能造成系统崩溃)。

程序改正:

void GetMemory2(char **p, int num)
{
    *p = (char *)malloc(sizeof(char) * num);
}
void Test2(void)
{
    char *str = NULL;
    GetMemory2(&str, 100); // 注意参数是 &str,而不是 str
    strcpy(str, "hello");
    cout<< str << endl;
    free(str);
}

将str的地址传给函数,对地址操作才能分配到内存空间。


二、数组与指针使用造成不同效果

char *GetString(void)
{
    char p[] = "hello world";
    return p; // 编译器将提出警告
}
void Test4(void)
{
    char *str = NULL;
    str = GetString(); // str 的内容是垃圾
    cout<< str << endl;
}

这里p[ ]是数组存放在栈区,所以”hello world”也存放在了栈区。而且是局部变量,局部变量离开该区域以后就被释放了,所以在Test4函数无法得到”hello world”。所以把数组改为指针就可以了。

修改char *GetString(void)

char *p = "hello world";

指针p虽然也存放在栈,但是它指向的”hello world”是一个常量。
函数 Test5 运行虽然不会出错,但是函数 GetString2 的设计概念却是错误的。因为GetString2 内的“hello world”是常量字符串,位于静态存储区,它在程序生命期内恒定不变。无论什么时候调用 GetString2,它返回的始终是同一个“只读”的内存块。

这里写图片描述


三、return使用不当

char *GetMemory3(int num)
{
    char *p = (char *)malloc(sizeof(char) * num);
    return p;
}
void Test3(void)
{
    char *str = NULL;
    str = GetMemory3(100);
    strcpy(str, "hello");
    cout<< str << endl;
    free(str);
}

用函数返回值来传递动态内存这种方法虽然好用, 但是常常有人把 return 语句用错了。这里强调不要用 return 语句返回指向“栈内存”的指针,因为该内存在函数结束时自动消亡。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值