C--有关内存的思考

C--有关内存的思考


#include <stdio.h>
#include <stdlib.h>
#include <string.h>


//结果段错误,因为str指向空,传递的是指针变量,要传变量地址才可以
void getmemory0(char *p)
{
    p = (char *)malloc(100);
}


void test(void)
{
    char *str = NULL;
    getmemory0(str);
    strcpy(str,"hello world");
    printf("%s\n",str);
}


//结果正确,传递了指针变量的地址
void getmemory1(char **p)
{
    *p = (char *)malloc(100);
}


void test1(void)
{
    char *str = NULL;
    getmemory1(&str);
    strcpy(str,"hello");
    printf("%s\n",str);
    free(str);
}


//返回栈内存,内存在函数结束时消亡,str不指向空,但也不指向hello
//结果可能正确,也可能是乱码
char *getmemory2(void)
{
    char p[] = "hello world";
    return p;
}


void test2(void)
{
    char *str = NULL;
    str = getmemory2();
    printf("%s\n",str);
}


//str变为野指针,修改动态内存区的内容,结果可能正确,也可能错误
//后果难以预料,非常危险
void test3(void)
{
    char *str = (char *)malloc(100);
    strcpy(str,"hello");
    free(str);
    if(str != NULL)
    {
	strcpy(str,"world");
	printf("%s\n",str);
    }
}


int main(int argc, char *argv[])
{
    test();
    //test1();
    //test2();
    //test3();
    return 0;
}


分析:
1.test()中:
如果函数的参数是一个指针,不要指望用该指针去申请动态内存。原因:编译器总是要为函数的每个参数制作临时副本,指针参数p的副本是_p,编译器使_p = p,如果函数体内的程序修改了_p的内容,就导致了p的内容作相应的修改,这就是指针可以用作输出参数的原因。但是,本例中,_p申请了新的内存,只是把_p所指向的内存地址改变了,但是p丝毫未变。所以getmemory并不能输出任何东西。
运行结果:程序崩溃,str仍然为NULL,strcpy运行错误。
2.test1()中:

如果非得要用指针参数去申请内存,那么应该传递“指向指针的指针”,即传&str。记得释放内存free(str)。

运行结果:能输出hello。

3.test2()中:
因为return语句返回了指向"栈内存"的指针,因为该内存在函数结束时自动消亡;执行str = getmemory()后,str不再是NULL指针,但str的内容也不再是“hello world”。
运行结果:可能是乱码,也可能是正确,str的内容是垃圾。
4.test3()中:
if(str != NULL)进行防错处理是没有用的,因为free/delete只是把指针所指向的内存给释放掉了,但并没有干掉指针本身,str被free以后,其地址仍不变(非NULL),只是该地址对应的内存是未知的,str成了野指针。
运行结果:出错,改动动态内存区的内容,后果难以预料,非常危险。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

书灯

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

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

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

打赏作者

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

抵扣说明:

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

余额充值