读书人

面试中碰到的一个关于内纯分配的有关问

发布时间: 2012-12-30 10:43:15 作者: rapoo

面试中碰到的一个关于内纯分配的问题,求高人指点
题目中给了3个函数,分别是:
1、
void GetMemory1(char * c)
{
c = (char *)malloc(100);
}

2、
char * GetMemory2()
{
char a[] = "Hello world";
return a;
}

3、
void GetMemory3(char ** c)
{
*c = (char *)malloc(100);
}

int main ()
{
char * a;
Getmemory1(a);

char * b = GetMemory2();

char * c;
Getmemory1(c);

strcpy(a, "Hello world");
strcpy(b, "Hello world");
strcpy(c, "Hello world");

return 0;
}

问,a b c分别出现什么结果,为什么?
//原题不是这样的,不过意思差不多,就是在函数中分配内存的问题。
//先谢谢了
[解决办法]
a的结果不可预料,这种操作方式很危险,因为Getmemory1传进去的,是a指针的副本,且是对副本进行修改,不是对a进行修改,而a指针指向的地方是未知的,执行此函数后,内存出现泄漏。

b,也得不到正确结果,Getmemory2函数内的变量为局部变量,退出则释放。

c,可以,Getmemory3函数,传的是指针的指针,实际上函数是对分配内存后,将指针赋给c。如此可以。
[解决办法]
char * a;
Getmemory1(a);
a 没有地址应该会爆掉吧


第二个数组也是会释放的





[解决办法]

引用:
a的结果不可预料,这种操作方式很危险,因为Getmemory1传进去的,是a指针的副本,且是对副本进行修改,不是对a进行修改,而a指针指向的地方是未知的,执行此函数后,内存出现泄漏。

b,也得不到正确结果,Getmemory2函数内的变量为局部变量,退出则释放。

c,可以,Getmemory3函数,传的是指针的指针,实际上函数是对分配内存后,将指针赋给c。如此可以。

++.这一题实际考不是内存分配,而是函数参数的传递。变量作为参数,如果直接传递变量,那就是只传递这个变量的副本。如果要函数里修改这个变量,则要传递变量的指针。
[解决办法]
3 是可以这样用的char * c; GetMemory3(&c);
[解决办法]
3看传的是什么,*c的话会很悲剧,1传c无压力,2会输出结果
b取的是变量char *c的值,c覆盖返回的a值
[解决办法]
第一个问题在于虽然能申请到内存空间,但首地址丢了,最后用的很有可能不是已申请的内存。
第二个问题在于退出函数后内存空间就被释放了,强行使用会带来意外的结果。
第三个函数没问题,但调用错了。应该是Getmemory1(&c);


[解决办法]
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,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、编译器、调试器、运行结果。
并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。
任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实!

有人说一套做一套,你相信他说的还是相信他做的?
其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗?

不要写连自己也预测不了结果的代码!

电脑内存只是一个一维二进制字节数组及其对应的二进制地址;
人脑才将电脑内存中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是很多数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、……

[解决办法]
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。


引用:
VC调试时按Alt+8、Alt+6和Alt+5,打开汇编窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应内存和寄存器变化,这样过一遍不就啥都明白了吗。
对VC来说,所谓‘调试时’就是编译连接通过以后,按F10或F11键单步执行一步以后的时候,或者在某行按F9设了断点后按F5执行停在该断点处的时候。
(Turbo C或Borland C用Turbo Debugger调试,Linu……

对新手,汇编和寄存器是不是要求有点高了?
maybe a breakpoint is enogh
[解决办法]
引用:
a的结果不可预料,这种操作方式很危险,因为Getmemory1传进去的,是a指针的副本,且是对副本进行修改,不是对a进行修改,而a指针指向的地方是未知的,执行此函数后,内存出现泄漏。

b,也得不到正确结果,Getmemory2函数内的变量为局部变量,退出则释放。

c,可以,Getmemory3函数,传的是指针的指针,实际上函数是对分配内存后,将指针赋给c。如此可以。


++
[解决办法]
1.

程序崩溃。
因为GetMemory 并不能传递动态内存,
Test 函数中的 str 一直都是 NULL。
strcpy(str, "hello world");将使程序崩
溃。

2

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

3

两种情况
(1)能够输出hello
(2)内存泄漏

读书人网 >C语言

热点推荐