你如何在C中传递结构指针?

时间:2013-04-26 01:20:24

标签: c pointers struct

我对如何通过引用在函数中传递指针感到有点困惑?

例如,这里是我编写的一些代码 (我没有复制整个函数,只是它的相关部分)

  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,但这只是抛出了一个无效的强制转换异常。将结构作为参数传递的最佳方法是什么?

三江源。

5 个答案:

答案 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)));