内存申请问题

lanlang12 2012-05-20 05:33:54
int *fun1()
{
int *p1;
p1=(int *)malloc(8);
return p1;
}
int *fun2(int *p2)
{
p2=(int *)malloc(8);
return p2;
}
同样是申请内存,p1是局部变量,p2是形参,可是fun1可以成功而fun2不能成功,如何深层分析这个问题?
...全文
197 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
aiyaya730 2012-05-21
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 的回复:]

1. 传递指针参数,其实也是值传递,也就是说传递进入fun2函数内部的是p2的一个副本,p2在函数fun2体外还是维持原来的状态,而不管fun2内部的p2(参数的副本)发生了何种变化。

2. 如果p2没有被初始化,那么其副本无法产生,因而会报错。在fun1中的p1,由于不需要产生副本,所以不会报错。
[/Quote]

这位大哥说得真好.

我刚看题目的时候还纳闷呢,觉得func2应该没啥问题,看到后面各种说不对,心里一阵发虚.
玩笑 2012-05-21
  • 打赏
  • 举报
回复
我只想说,两个都是局部变量,只是一个没初始化,一个用实参初始化了,后者相对前者,实参初始化简直是多余
pathuang68 2012-05-21
  • 打赏
  • 举报
回复
1. 传递指针参数,其实也是值传递,也就是说传递进入fun2函数内部的是p2的一个副本,p2在函数fun2体外还是维持原来的状态,而不管fun2内部的p2(参数的副本)发生了何种变化。

2. 如果p2没有被初始化,那么其副本无法产生,因而会报错。在fun1中的p1,由于不需要产生副本,所以不会报错。
pathuang68 2012-05-21
  • 打赏
  • 举报
回复
楼上各位是不是没有仔细看楼主的问题?尽管俺也不甚赞成fun2那样的写法,但fun2的写法是没有问题的:

int *fun2(int *p2)
{
p2=(int *)malloc(8);
return p2; // 作为返回值,没有任何问题,楼主并没有试图用p2作为返回参数。
}

我猜楼主的意思是:

int *fun1()
{
int *p1;
p1=(int *)malloc(8);
return p1;
}

int *fun2(int *p2)
{
p2=(int *)malloc(8);
return p2;
}

int main(int argc, char** argv)
{
int *p;// = 0; // 如果不初始化,调用fun2就出错
cout << fun1() << endl;
cout << fun2(p) << endl;

return 0;
}

如果p没有初始化,调用fun2(p)为什么会出错吧?(p如果初始化了,调用fun2就没有问题)
赵4老师 2012-05-21
  • 打赏
  • 举报
回复
VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习汇编以及C和汇编的对应关系。
从汇编的角度理解和学习C语言的指针,原本看似复杂的东西就会变得非常简单!
指针即地址。“地址又是啥?”“只能从汇编语言和计算机组成原理的角度去解释了。”

提醒:
“学习用汇编语言写程序”

“VC调试(TC或BC用TD调试)时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
(Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。)
想要从本质上理解C指针,必须学习C和汇编的对应关系。”
不是一回事!

不要迷信书、考题、老师、回帖;
要迷信CPU、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!
Xomic 2012-05-21
  • 打赏
  • 举报
回复
第一个临时变量,当然可以 ,不需要纠结吧!
第二个是传值调用,用
int *fun2(int **p2)
{
p2=(int *)malloc(8);
return p2;
}
AnYidan 2012-05-21
  • 打赏
  • 举报
回复
林锐<高质量 c\c++ 编程>
ahumoon7421 2012-05-20
  • 打赏
  • 举报
回复
请问 这两个有本质区别么?返回的是指针, 对于第二个函数 你在主调函数里面写上
p2 = fun2(p2);
这和第一个没有分别!
可能楼主想说的是
int fun2(int *p2)
{
p2=(int *)malloc(8);
return 0;
}
这样的话,你就应该这样
int fun2(int **p2)//改变指针的指向
{
*p2=(int *)malloc(8);//要注意确保不会内存泄露
return 0;
}
youkuxiaobin 2012-05-20
  • 打赏
  • 举报
回复

int *fun2(int **p2)
{
*p2=(int *)malloc(8);
return *p2;
}

不是分配不成功,是你用错了
kevin_khb 2012-05-20
  • 打赏
  • 举报
回复
编译器要为函数的参数设置一个副本,指针参数p2的副本_p2,p2 = _p2,如果修改_p2的内容,也就修改了p2的值,但是如果malloc,只是把_p2所指的内存地址改变了,p2并没变化
猪头小哥 2012-05-20
  • 打赏
  • 举报
回复
你这是要改变形参的值啊,好好研究下形参是怎么传递的吧!
你如果是初学者,你肯定还记的谭浩强那本书上在讲交换两个数的那个例子,形参是值传递,关于什么是值传递,自己查,而你这的形参是一个地址,那也不例外。
W170532934 2012-05-20
  • 打赏
  • 举报
回复
fun1返回的是指针的值,那么调用者将获得这个值,然后可以得到申请的内存的首地址,而func2返回的是形参p2的值,而p2是个形参,地址是在传递的时候就确定的。具体的可以看下这帖子。
http://topic.csdn.net/u/20120319/15/0751ad00-bad3-481b-9f3a-fed7409cb9cc.html
fthislife 2012-05-20
  • 打赏
  • 举报
回复

int *fun2(int *&p2)
{
p2=(int *)malloc(8);
return p2;
}
或者
int *fun2(int **p2)
{
*p2=(int *)malloc(8);
return *p2;
}

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧