访问位于另一个结构体指针内部的结构体指针中的元素

4

我想学习嵌套结构体指针的工作原理。如果我要访问一个指向另一个结构体指针中的结构体元素,应该怎么做?谢谢。

#include <iostream>

typedef struct
{
  unsigned int            a;
  unsigned int            b;
  unsigned int            c;
} inner;

typedef struct
{
  unsigned int            d;
  unsigned int            e;
  inner * in;
} outer;

/* Function to use struct */
void test(outer * out)
{
  //Update the value of out->in->a.
  out->in->a = 5;
}

int main() {
  outer * out;
  test(out);

  std::cout << "My updated value: " << out->in->a << std::endl;
}

我遇到了"Segmentation fault (core dumped)"的错误。
注:根据建议进行了修改。
#include <iostream>

typedef struct
{
    unsigned int            a;
    unsigned int            b;
    unsigned int            c;
} inner;

typedef struct
{
    unsigned int            d;
    unsigned int            e;
    inner * in = new inner();
} outer;

/* Function to use struct */
void test(outer * out)
{
    //Update the value of out->d.
    out->d = 3; 
    //Update the value of out->in->a.
    out->in->a = 5;
}

int main() {

    outer out; 
    outer* p = &out; 

    test(p);

    std::cout << "My updated value for d: " << p->d << std::endl;
    std::cout << "My updated value for a: " << p->in->a << std::endl;
}

我现在得到了正确的更新值。但是我现在有一个警告:
"warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11"
inner * in = new inner();

我该如何修复这个警告?


2
你的问题是你只有一个指向 out 的指针。你需要先分配内存。 - Hayt
这仍然会失败,因为“in”没有记忆。 - Hayt
抱歉,你为什么要再次使用那些typedef? - Arnav Borborah
你应该先熟悉C++和指针。也许可以在这里看一下http://www.cplusplus.com/doc/tutorial/dynamic/。在这个Stackoverflow问题中解释所有内容可能有点太多了。 - Hayt
4个回答

2

首先,C和C++是不同的编程语言。

无论如何,在访问指针所指向的元素之前,您必须先分配结构体。否则,使用未初始化的指针或指向无效结构体对象的指针将导致程序出现未定义的行为。

下面是一个演示如何使用指针访问结构体元素的C程序:

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

typedef struct
{
  unsigned int            a;
  unsigned int            b;
  unsigned int            c;
} inner;

typedef struct
{
  unsigned int            d;
  unsigned int            e;
  inner * in;
} outer;


int main( void ) 
{
    outer *out = malloc( sizeof( outer ) );

    if ( ( out != NULL ) && ( out->in = malloc( sizeof( inner ) ) ) )
    {
        out->in->a = 1;
        out->in->b = 2;
        out->in->c = 3;

        printf( "out->in = { a = %d, b = %d, c = %d }\n", out->in->a, out->in->b, out->in->c );

        free( out->in );
        free( out );
    }

    return 0;
}

它的输出是

out->in = { a = 1, b = 2, c = 3 }

在C++中,程序可以如下所示:
#include <iostream>

typedef struct
{
  unsigned int            a;
  unsigned int            b;
  unsigned int            c;
} inner;

typedef struct
{
  unsigned int            d;
  unsigned int            e;
  inner * in;
} outer;

int main() 
{
    outer *out = new outer;

    out->in = new inner;

    out->in->a = 1;
    out->in->b = 2;
    out->in->c = 3;

    std::cout << "out->in = { a = " << out->in->a
              << ", b = " << out->in->b
              << ", c = " << out->in->c
              << " }" << std::endl;

    delete out->in;
    delete out;

    return 0;
}

它的输出将与上面显示的相同。

至于这个函数

void test(outer *out)
{
  //Update the value of out->in->a.
  out->in->a = 5;
}

那么指针outin都必须指向有效的outerinner类型的对象。


0
在你的test()函数中,out没有指向任何有效的内存位置。试图对该指针进行解引用将会导致未定义行为
因此,你需要在main()中为out分配内存,并将其传递给test()
之后,out->in也是一个指针,你需要为该指针分配内存,以便它指向一个有效的内存位置。在确保所有指针都指向有效的内存位置之后,你可以继续对它们进行解引用操作。

0

首先,您只有一个指向out的指针,而目前没有分配内存:如@IgorTandetnik所说,请执行以下操作:

outer out; outer* p = &out; test(p);您有一个未初始化的指针,它并未指向任何有效内容。

当test使用out时,通过取消引用它,您基本上是未定义的行为,这与取消引用未指向任何内容的指针一样。

接下来,您对in也存在同样的问题,因为它也没有分配内存。通过为in分配内存来解决该问题,这也像以前一样会导致未定义行为。

此外,我很困惑为什么您需要那些typedefs,但又标记了您的问题。如果您正在使用c编译器编译,则有意义,但否则,在C++编译器中,您不需要使用struct前缀,因为编译器已经为您完成。


我的主函数有一个外部结构体并可以传递到函数中。访问任何外部结构体元素都可以工作。但现在我该如何为内部结构体分配内存?我尝试了 inner in; inner* q = ∈ - daemoner119
在你的test()函数中,先执行out->in = new inner()代码。 - Arnav Borborah

0

解引用指针应该在某种分配形式之后进行。

在您的函数中,out->in->a = 5; 得到了一个已声明但未初始化的指针。在此之前,您应该做一些类似于 out = new outer(); 的操作,但是只有 out 指针才能被解引用 [实际上,在此之前也可以解引用,但这会导致 UB - 不好的行为],所以现在您还应该为 in 指针分配内存,如下所示:out->in = new inner(); 就这样:

/* Function to use struct */
void test(outer * out)
{
  //Update the value of out->in->a.
  out->in = new inner();       // addition
  out->in->a = 5;
}

int main() {
  outer * out;
  out = new outer();   // addition

  test(out);

  std::cout << "My updated value: " << out->in->a << std::endl;
}

注意:我使用了new,因为你使用了#include <iostream>,这意味着是C++。如果使用C语言,请使用malloc代替。


这个和我的代码一样,但是我得到了以下警告: warning: non-static data member initializers only available with -std=c++11 or -std=gnu++11inner *in = new inner(); - daemoner119

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接