分配内存的问题

一、使用内存分配应该注意的问题

检查内存是否分配成功,内存声明周期程序结束时要释放,避免导致内存泄露。使用过程中避免指针越界访问。

创建内存分配函数例子:(malloc是分配多少个字节的内存,里面是数字,且malloc分配的是堆上的内存,不是栈里面)

二、分配内存实例

void GetMemory(char*p)

{

p = (char*)malloc(100);

}

void Test(void)

{

char *str = NULL;

GetMemory(str);

strcpy(str,"hello world");

printf(str);

}

malloc()分配了新的内存给p(也就是说p里面存储的或指向的是在堆里面的内存),但是你原来函数中的p是复制了str的值(str传递进去的是指针指向的地址,为NULL,不是存储str的地址。所以你可以改变的是str里面存储的地址指向内存的值)进行操作。函数执行完之后p就找不到了(因为存储p的地址是在栈上临时分配的内存),你的str并没有得到p的值,同时你把p丢了,也没有办法回收分配给p的内存。

故Test函数中的 str一直都是NULL,它并没有指向任何内存,strcpy(str, "helloworld")也不会执行成功,将使程序崩溃。

有两种办法可以改变这种情况:

第一种:传递给形参的是指针的地址。

如果改成指针变量的地址传入即二级指针则不一样。因为传递进去的是指针变量的地址,这样就可以修改指针变量地址存储的地址,即分配了内存给指针变量去指向的地址。

void GetMemory(char **p)

{

p = (char*)malloc(100);

}

void Test(void)

{

char *str = NULL;

GetMemory(&str);

strcpy(str,"hello world");

printf(str);

}

第二种办法就是返回值是内存的地址,也就是返回指针变量。

这种办法在链表中常常用到。如下所示,返回在堆里面的分配的地址,然后将地址赋值给指针变量。

char* GetMemory(char*p)

{

     p = (char*)malloc(100);

     return p;

}

void Test(void)

{

char *str = NULL;

str=GetMemory(str);

strcpy(str,"hello world");

printf(str);

}

三、类似于fun1(char c);fun2(char *c);

main()

{

    char a='a';

    char *p=&a;

    fun1(a);传递进去的是c里面存储的值'a';

    fun2(p);传递进去的是c的地址;

}

1、如果我们在fun1里面改变c的值,在main里面a的值是不会改变的,依然是'a';

同理,我们在fun2里面改变指针(地址变量)c的值,不能改变在main里面p的值,依然是a的地址。

2、这是因为实参传递给形参的是值传递,就是将实参内存里面存储的值拷贝给形参,而不是将内存地址传递给形参;

同理,函数fun里面,会在栈里面给形参分配内存,而内存里面存储的就是实参拷贝的值。

3、所以,我们可以在fun2里面可以改变c存储的地址(&a)所存储的值a('a');

同理,如果我们在fun2里面,改变c原来所存储a的地址,也就是c里面存储是堆的地址(c=(char*)malloc(sizeof(char))),跟p没有关系。

在main里面p的值,依然是a的地址。

4、在函数里面分配的临时内存,在退出函数后会销毁。这时候c里面存储是堆的地址(c=(char*)malloc(sizeof(char)))也就

没有了,那这块在堆里面分配的内存也就找不到了,而堆不会销毁,只有等程序退出才会释放内存。

5、如果要改变p所存储a的地址,要传递的是p的地址给函数fun。


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值