【问题标题】:Returning a pointer to structure from a function从函数返回指向结构的指针
【发布时间】:2016-04-21 06:45:58
【问题描述】:

我一直在尝试使用以下代码和一个接受结构并返回指向它的指针的函数从函数返回指向结构的指针:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

struct mystruct
{
    int id;
    char name[10];
};


//this is the function
struct mystruct *return_pointer(struct mystruct a)
{
    struct mystruct *ptr;
    ptr = &a;
    return ptr;
}

int main()
{
    struct mystruct tag, *p;
    tag.id = 12;
    strcpy(tag.name,"abcd");

    printf("Values are: %d\t%s",tag.id,tag.name);
    p=return_pointer(tag);

    printf("\nValues through pointer: %d\t%s", p->id, p->name);
    return 0;
}

但是当我尝试使用返回的指针访问结构的值时,它无法正常工作。它只显示“id”而不显示“名称”。 这里可能存在什么问题? 我读过一本书,说要在函数体中使用它:

ptr = (struct mystruct *)malloc(sizeof(struct mystruct));
ptr-> id = a.id; 
strcpy(p->name,a.name); 
//struct 'a' is argument to function

return ptr;

如果这是正确的解决方案,那么为什么会这样呢?

【问题讨论】:

  • return_pointer 函数的目的是什么?这似乎毫无意义。
  • @MichaelWalz 不要故意!

标签: c pointers structure


【解决方案1】:

因为您要返回 a,它是您传递的那个的副本。 中的参数是按值传递的,因此atag 的副本分配在不同的地方,那个地方是函数的堆栈帧,当函数返回时它被销毁。

因此,在打印时,您正在打印已释放的struct,这是未定义的行为。如果您希望您的代码无论出于何种原因都能正常工作,请尝试此操作

struct mystruct *
return_pointer(struct mystruct *a)
{
    return a;
}

并在main() 中将其更改为

p = return_pointer(&tag);
//                 ^ Pass the address of tag and return it
//                   the same as
//                    
//                                   p = &tag;
//
//                   which is why they say it's pointless in
//                   the comments

当你使用malloc()时,你在堆上分配struct,数据在任何可访问的地方都是有效的1直到你用free()手动销毁它,free()函数将简单地释放内存,它不关心以后会用它做什么,它只是把它还给它来自哪里。

另外,请务必检查malloc() 的返回值。


1只要有一个指针保存malloc()返回的原始内存地址。当您决定不再需要 struct 时,这正是您必须传递给 free() 的地址。

【讨论】:

  • 但实际上,只要p = &amp;tag; 就可以了。
  • @Caleb,我知道请看最终答案。
  • 抱歉,错过了您的评论,但如果我们都说 10 或 12 次,消息可能会通过。 ;-)
【解决方案2】:

你应该这样做:

p = &tag;

指向同一个结构tag。不要这样做:

p = return_pointer(tag);

因为当您传递tag 时,您按值传递它并创建一个副本(在函数return_pointer 中称为a)因此,您的taga(特别是函数中的地址(即&amp;tag&amp;a)不同 - 请参阅 Caleb 先生的评论)。

【讨论】:

  • 具体来说,&amp;tag&amp;a 会有不同的值。
  • @Caleb 啊,是的,你是对的。那更准确。
【解决方案3】:

函数参数是函数的局部变量。它们在函数完成工作后被销毁。

您要做的是通过引用传递一个结构并返回对它的引用。在这种情况下,函数看起来像

//this is the function
struct mystruct * return_pointer( struct mystruct *ptr )
{
    return ptr;
}

并像这样称呼

p = return_pointer( &tag );

虽然这样的功能并没有太大的用处。尽管如此,一般来说,它可以更改传递对象的一些数据成员。

【讨论】:

  • 这样的函数没什么用处...我能想到一些,包括调用一个库的应用程序,该库为 @987654321 的多个订阅提供服务@ 网络,对库的简单调用可以将信息传递给库,并通过struct * 更新应用程序。不过,很好的答案。
【解决方案4】:

我是一个来自中国的代码初学者,你的代码的错误是局部变量的域(ptr是一个指针)只在函数中有效,但是当你将它返回到你的全局主函数时,它指向的内存已被释放。所以它变成了一个错误。很高兴回答您的问题!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-30
    相关资源
    最近更新 更多