【问题标题】:Why do I need to create a struct and then a pointer to it's address?为什么我需要创建一个结构然后指向它的地址的指针?
【发布时间】:2022-01-20 21:02:17
【问题描述】:

我在 C 程序中使用 comedilib,我正在尝试理解这一行:

comedi_cmd c, *cmd = &c;

comedi_cmd 是一个结构,它包含一堆整数和一个指向数据数组的指针。变量c 不在其他任何地方使用。如果我省略创建 c 而只是这样做:

comedi_cmd *cmd;

...然后我开始遇到段错误。

为什么我们不能简单地创建指向comedi_cmd 结构的指针?这是一种分配内存的方式吗?

这是我不知道的 C 魔法吗?

有关更多上下文,comedilib 示例中有问题的行在这里: https://github.com/Linux-Comedi/comedilib/blob/master/demo/tut3.c#L68

【问题讨论】:

  • 这是因为它需要将它传递给需要指针的函数。 “为什么我们不能简单地创建指针”。你当然可以,这实际上就是cmd。但是您仍然需要将其指向某些东西。如果您的意思是别的,请说明您想到的代码。
  • comedi_cmd *cmd; 这只是创建了一个未初始化的指针。您需要先将其指向某物,然后才能使用它。否则它里面有一个垃圾值,而不是它需要的结构的有效地址。
  • 我曾认为我使用comedi_cmd 类型的事实表明cmd 应该指向代表结构的内存地址,但我可以看到他们没有跟进用 malloc 或任何东西。也许等效的初始化是:comedi_cmd *cmd = NULL; cmd = malloc(sizeof(comedi_cmd));
  • 是的,这是另一种方法。但是,如果结构不需要保留在当前函数之外,那么完全按照所示使用局部结构变量会更简单且同样有效。在这两种情况下,cmd 最终都会指向一个有效的结构。
  • "cmd 应该指向一个代表结构的内存地址"。嗯,确实如此。这正是cmd = &c 所做的。为什么你认为它在那之后没有指向结构?

标签: c linux memory


【解决方案1】:

让我们把这行分成两行:

comedi_cmd c;
comedi_cmd *cmd = &c;

第一行的作用是在堆栈上分配足够的内存以包含comedi_cmd 类型的变量c。这就是你的一堆整数和一个指针将存储在内存中的地方。

第二行定义了cmd,一个指向comedi_cmd的指针,并用c的地址初始化它,这是整串整数和一个指针在内存中存储的地方。

如果您要定义 cmd 未初始化:

comedi_cmd *cmd;

那么它将有一个未定义的值(地址)。正如您所观察到的,取消引用它可能会导致SIGSEGV。您必须确保cmd 指向有效内存,而c 在这种情况下是有效内存。

【讨论】:

  • 谢谢,在阅读了@kaylum 的 cmets 之后,我清楚地知道我错过了什么。来自具有更高级别语言(如 Python)的背景,我认为参考 cmd 的内存分配是理所当然的。我接受了这个,因为我觉得它给出了最明确的答案。
【解决方案2】:

很明显,您需要创建一个结构类型的对象,其中包含“一堆整数和一个指向数据数组的指针”。

此对象将在某些功能中更改。要在函数中准确更改对象而不是对象的副本,您需要通过引用将其传递给函数。

在 C 中,通过引用传递意味着通过指向对象的指针间接传递对象。取消引用指针函数将直接访问传递的对象。

你可以写例如调用一个函数

some_function( &c );

但是你可以引入一个指针类型的中间变量,比如

comedi_cmd *cmd = &c;

并在函数调用中使用它而不是表达式&c

some_function( cmd );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多