我对如何通过引用在函数中传递指针感到有点困惑?
例如,这里是我编写的一些代码 (我没有复制整个函数,只是它的相关部分)
metadata * removeBlock(metadata *first)
{
metadata *temp = first;
if(first == NULL || first -> prev == NULL)
{
first -> in_use = 1;
first = NULL;
return temp;
}
}
我想要的是当函数返回时,传入的原始值应该设置为NULL。 这是我如何调用函数,(这行代码将从堆中的区域中提取元数据结构,它正常工作,我已经调试并确保在此之后,struct真正指向有效的元数据结构)
metadata *strct = ((metadata *)ptr - sizeof(metadata));
removeBlock(strct);
但是,在此方法返回后,strct仍然是我在函数中传递之前的值。我尝试传入& strct,但这只是抛出了一个无效的强制转换异常。将结构作为参数传递的最佳方法是什么?
三江源。
答案 0 :(得分:2)
我不认为你想要的是一个好的设计 - 如果你的函数的用户希望指针设置为null(为什么?),那么使用函数的返回值重置值是有意义的。 p>
无论如何,你需要一个指向指针的指针,如下所示:
metadata* removeBlock(metadata** first) {
metadata* temp = *first;
if( temp == NULL ) return temp;
if( temp->prev == NULL ) {
temp->in_use = true;
*first = NULL;
}
return temp;
}
metadata* strct = ((metadata*)ptr - sizeof(metadata));
removeBlock(&strct);
答案 1 :(得分:1)
正如@SheerFish所说,我们在C中所拥有的只是传值。但是,可以用指针模拟传递引用。
void func(struct foo **fooptr) { *fooptr = 0; }
int main(int argc, char **argv) { struct foo *fooptr; func(&fooptr); }
这是将指针ptr
传递给变量的值(如果该值是指针,请不要介意),允许函数使用*ptr
的原始值进行播放。这种技术有时被称为按地址传递,并且是最接近的C必须通过引用传递。
答案 2 :(得分:1)
如果您通过'C中的引用',则需要记住通过 - > / **和*引用和引用。我写的这段代码可能对你有所帮助
int delete_node(struct node** head, int target)
{
if(*head == NULL)
return 0;
if((*head)->data == target)
{
temp = *head;
*head = (*head)->next;
free(temp);
return 1;
}
}
函数调用:
delete_node(&head, data)
您正在使用直接内存指针操作。您将结构的位置丢弃在内存中,取消引用它,然后更改该内存位置的值。
答案 3 :(得分:1)
我没有阅读所有细节,但这部分跳出来是不正确的:
(metadata *)ptr - sizeof(metadata)
指针算法以类型为单位完成,而sizeof
则以字节为单位进行测量。
所以我怀疑你想说的是:
(metadata *)(((char*)ptr) - sizeof(metadata))
这也是对您正在运行的计算机做出一些假设,即metadata
可能需要填充以确保字段正确对齐以供此用途使用。如果sizeof(metadata)
不是字大小的倍数,那么很多架构都会失败。 (但是x86会让它滑动,尽管有性能成本和一些影响,比如原子操作不能在这些领域工作。)
答案 4 :(得分:1)
指针按值传递。 c中的任何按值传递。所以为了更改传递给函数的指针,它应该会收到metadata **first
。
此外,你应该使用
metadata *strct = ((metadata *)ptr - 1);
因为指针算术是以sizeof(* p)的倍数完成的。所以这相当于
metadata *strct = ((metadata *)((char*)ptr - sizeof(metadata)));