传递二维指针,函数内部开辟空间,

月光xia漫步 2013-10-30 10:15:52
请教大家一个通过传递二维指针,在函数内部开辟空间,函数外部使用该内存并释放的问题。
下面是一个在函数内部开辟空间,函数外部操作内存的例子:

void GetMemory( char **p, int num )
{
*p = (char *) malloc( num );
}
void Test( void )
{
cout<<"in fun Test:"<<endl;
char *str = NULL;
//char **str2=NULL;
GetMemory( &str, 100 );
//GetMemory((str2,100));
strcpy( str, "hello\n" );
printf( str );
}

函数可以正确执行,那么如果在调用的时候使用下面的方式:

void Test( void )
{
cout<<"in fun Test:"<<endl;
char **str2=NULL;
GetMemory((str2,100));
strcpy( str, "hello\n" );
printf( str );
}

通过上述的方式,却不能达到相同的目的。
我感觉传递一个二维指针和一个一维指针的地址(二维指针)应该是一样的,再加上我在调用之前都是为指针置空,所以感觉效果应该一样。
希望大家给一点建议,谢谢!
...全文
271 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
tsakang 2013-10-30
  • 打赏
  • 举报
回复

第一种char* str = NULL; //&str传参时是有地址空间的,形如0x0012ff7c
第二种char** str = NULL; //str传参时地址是0x00000000

你可以在编译器中watch窗口看一下两种传参的地址!
传参传0x00000000会有什么后果可想而知!
max_min_ 2013-10-30
  • 打赏
  • 举报
回复
第一个例子你定义的是 char * str = NULL, str指针的指向地址为NULL而已! 但是它本身的地址是有效的!也就是会所 &str这个值是有效的! 第二个例子你定义的是 char ** str = NULL , 指针的指针为NULL, 也就是指针本身的地址也是为NULL的,所以当你传参数的时候传指针的地址为NULL的了,这个时候你在它基础上给它指向的地址分配空间是不行的,得先给它本身分配空间后,再给它指向分配空间!
绿皮蛙 2013-10-30
  • 打赏
  • 举报
回复
第一个char* str = NULL; 你已经给这个str赋值了 也就是说需要有一个内存来保存了NULL这个值,保存这个值的内存地址的值就是&str 也就是**str 你把这个2级指针传进去了 *p的时候他的内容就是NULL 然后你给他重新赋值了 第二个char **str =NULL; 你传到函数里 运行时 *p的时候就会报错 意思是取NULL这个地址的值 取不到
lin5161678 2013-10-30
  • 打赏
  • 举报
回复
值传递
赵4老师 2013-10-30
  • 打赏
  • 举报
回复
计算机组成原理→DOS命令→汇编语言→C语言(不包括C++)、代码书写规范→数据结构、编译原理、操作系统→计算机网络、数据库原理、正则表达式→其它语言(包括C++)、架构…… 对学习编程者的忠告: 眼过千遍不如手过一遍! 书看千行不如手敲一行! 手敲千行不如单步一行! 单步源代码千行不如单步对应汇编一行! VC调试时按Alt+8、Alt+7、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+7、Alt+6和Alt+5,打开汇编窗口、堆栈窗口、内存窗口和寄存器窗口看每句C对应的汇编、单步执行并观察相应堆栈、内存和寄存器变化,这样过一遍不就啥都明白了吗。 (Linux或Unix下可以在用GDB调试时,看每句C对应的汇编并单步执行观察相应内存和寄存器变化。) 想要从本质上理解C指针,必须学习C和汇编的对应关系。” 不是一回事! 不要迷信书、考题、老师、回帖; 要迷信CPU、编译器、调试器、运行结果。 并请结合“盲人摸太阳”和“驾船出海时一定只带一个指南针。”加以理解。 任何理论、权威、传说、真理、标准、解释、想象、知识……都比不上摆在眼前的事实! 有人说一套做一套,你相信他说的还是相信他做的? 其实严格来说这个世界上古往今来所有人都是说一套做一套,不是吗? 不要写连自己也预测不了结果的代码! 电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息…… 十字链表交换任意两个节点C源代码(C指针应用终极挑战)http://download.csdn.net/detail/zhao4zhong1/5532495
月光xia漫步 2013-10-30
  • 打赏
  • 举报
回复
第二个定义了
 char ** str = NULL;
指针的指针为空,难道就可以证明指针也为空吗? 还有你说要先为指针的指针开辟空间,是不是按照下面的方式:
char **str2=(char **)malloc(128);
我现在有点晕了! 谢谢您的回复!
引用 1 楼 max_min_ 的回复:
第一个例子你定义的是 char * str = NULL, str指针的指向地址为NULL而已! 但是它本身的地址是有效的!也就是会所 &str这个值是有效的! 第二个例子你定义的是 char ** str = NULL , 指针的指针为NULL, 也就是指针本身的地址也是为NULL的,所以当你传参数的时候传指针的地址为NULL的了,这个时候你在它基础上给它指向的地址分配空间是不行的,得先给它本身分配空间后,再给它指向分配空间!
月光xia漫步 2013-10-30
  • 打赏
  • 举报
回复
虽然第二种
char** str = NULL; //str传参时地址是0x00000000
但是第一种
char* str = NULL; //虽然str传参时是有地址空间的的,但是str地址也是0x00000000
这个不知道有没有影响?
引用 2 楼 tsakang 的回复:

第一种char* str = NULL; //&str传参时是有地址空间的,形如0x0012ff7c
第二种char** str = NULL; //str传参时地址是0x00000000

你可以在编译器中watch窗口看一下两种传参的地址!
传参传0x00000000会有什么后果可想而知!
1) 本套课程针对高校大学生系统学习C语言而录制,从0基础入门讲起,循序渐进,通俗易懂,同时适用于计算机系及非计算机系的同学。通过学习可以帮助大家掌握C语言本质,轻松面对C语言全国二级考试,并达到能独立完成中型C项目、C游戏的水平;2) 多数高校都开设了C语言课程,网上C语言课程也很多,但普遍存在两个问题: (1) 授课方式单一,大多是照着代码念一遍, 对刚刚接触编程的同学来说,感觉晦涩难懂 (2) 授课内容过度注重语法,没有项目实战支撑,造成课程枯燥无趣。本课程针对上述问题进行了改进 (1) 授课方式采用语法讲解+内存布局示意图+项目的方式,让课程生动有趣好理解 (2) 系统全面的讲解了C语言的核心技术点,还配套录制了《全国计算机二级C语言真题精讲》,让学员在掌握C语言编程的同时,还能轻松面对二级考试;3) 课程详细内容: 常量-变量、分支语句、循环语句、操作符和表达式、函数(库函数、自定义函数、递归调用 )、数组(一维数 组、二维数组、数组作为函数参数、指针数组)、指针(指针指针类型、二级指针和多级指针指针表达式解析、指针运算、数 组指针函数指针、回调函数)、调试技巧、程序环境和预处理(翻译环境、运行环境、预定义符号、#define和#undef、宏和函 数、条件编译、文件包含)、 数据在内存中的存储、内存块分配、static、字符函数和字符串函数、自定义类型(结构体、枚举 、联合)、动态内存管理、文件操作(i/o常量、i/o函数、流)。

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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