如何通过函数修改指向void的指针?

时间:2011-02-08 20:26:25

标签: c pointers void void-pointers

3 个答案:

答案 0 :(得分:7)

我认为你需要

void newData(void ** d) 
{
    char data[] = "world";
    *d = &data;  
}     

然而,这有它自己的问题,因为“world”是堆栈本地的,并且从newData返回后将无效。

答案 1 :(得分:4)

这有两个问题:

char data[] = "world";

可能是作为函数堆栈框架的一部分创建的。数组降级为指针。因此,当函数调用ret时,它应该清理它的堆栈并且该地址的内存消失了。如果这里有任何操作,那是因为你还没有覆盖内存。

你能做什么?声明它static是一个保证(至少根据c99)程序生存期存在的解决方案(即它不会在堆栈上分配但在数据段中,并且c库在main之前为你分配它)。但是,由于我怀疑这只是一个演示,所以值得指出:

char data[] = "world";
memcpy(d, data, 5);

完全有效,因为您正在复制内容而不是指向值。

newData(&testPointer);

你在这里犯了一个简单的错误。汇编中的指针是一个存储另一个存储器地址的存储器地址。当您将指针传递给函数时,您希望传递该内存地址,以便在调用该函数时,指针的内容(内存地址)以新指针的形式复制到堆栈中。当然,这两个指针都指向同一个东西,这就是你最终如何实现pass-by-reference类型的东西。如果您不相信我,请在调试器中观看。

但是,您正在做的是传递指针的地址,因此您正在创建指向值的指针。想象一下这样的记忆:

|Address|Value
|0x120  |0x121    <-- this is what you're passing with &testPointer
|0x121  |0x122    <-- this is a pointer; it contains the address of a value
|0x122  |h        <-- this is a value.
|0x123  |e
|0x124  |l
...

我希望这更清楚。在我的简单记忆中,你传递0x120而不是0x121。你当然可以解除引用两次,但为什么呢?简单的解决方案就是像这样传递指针:

newData(testPointer);

答案 2 :(得分:0)

我认为代码可以解决问题的一点变化:

void newData(void ** d)
{
    char* data = "world";

    *d = data;
}