指针参数传递中的玄机

之前在写数据结构(链栈)的算法实现的时候出现了一个小问题,我想要实现元素入栈的功能,函数的原型及定义如下:

LinkStack* PushElem(LinkStack *linkstack,int element)
{
	if (IsEmptyStack(linkstack))
	{
		cout<<"该栈为空,无法插入元素"<<endl;
		return linkstack;
	} 
	else
	{
		LinkNode *newnode=new LinkNode;
		if (!newnode)
		{
			cout<<"内存分配失败"<<endl;
			return linkstack;
		}
		else
		{
			newnode->data=element;
			newnode->next=linkstack->top;
			linkstack->top=newnode;
			return linkstack;
		}
	}
}
但是奇怪的是,如果不用一个新的LinkStack变量去存储PushElems()函数的返回值的话,传入该函数的LinkStack*指针变量是不会发生改变的。之前认为的是当我给函数传入指针参数的话,该指针所指向的内容应该会发生改变啊!结果却并没有改变。后来在《编写高质量代码——改善C++程序的150个建议》找到了答案。书里面提到了一个例子:
void GetMemory(char *pStr,int num)
{
	pStr=new char[num];
}
int main()
{
	char *strHello=NULL;
	GetMemory(strHello,100);
	strcpy(strHello,"Hello C++ Tips");
	delete [] strHello;
	return 0;
}
其实该示例是无法改变strHello的内存的, strHello的内存依旧为NULL,所以当把字符串复制给strHello时,程序会崩溃。书里给的解释如下:

 “指针函数的每个参数,编译器都要为其生成一个临时副本,指针参数pStr的副本为_pStr,并且会使_pStr=pStr=0x00000000。

在函数内的程序修改了_pStr的内容,也就是改变了_pStr的内存地址,而pStr却丝毫未变,仍旧为NULL。所以函数GetMemory

不能输出任何东西。不仅如此,每执行一次该函数就会造成新的一块内存泄漏。”

将GetMemory函数修改如下:

void GetMemory(char **p,int num)
{
     *p=new char [num]
}
“实参str传入函数GetMemory时,传入的是存放指针str的地址address_str,编译器为其生成临时副本_address_str,并且_address_str=address_str=0x000f1850(可能是任意非NULL地址),因此在执行函数语句前,_address_str指向的也是0x00000000。在函数内部,程序修改了_address_str所指向的内存地址,因为两者应指向相同的地址,所以address_str所指向的地址也会发生改变,那么采用指针的指针这种方式可以实现动态内存的传递。

之前我定义链栈的结构体如下:

typedef struct node
{
	int data;
	struct node *next;
}LinkNode;
所以如果要改成指针的指针的话,应该修改为下面的这种定义:

typedef struct node
{
	int data;
	struct node *next;
}LinkNode,*LinkStackPtr;
typedef struct LinkStack
{
	LinkStackPtr top;
}LinkStack;
所以LinkStack*为一个指针,该指针指向的是LinkStackPTR*(这个同样也是个指针)。所以修改之后便可以达到指向指针的指针的目的了。所以当把LinkStack*传入函数后,函数体内部对指针的修改在函数生命周期结束后依旧有效,可以到达修改的目的。如果你需要修改int*的内容,那么你应该传递int**给函数,同理其他的也是如此。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值