【问题标题】:Create a variable-length int array inside a structure using a pointer使用指针在结构内创建可变长度 int 数组
【发布时间】:2017-07-25 17:09:46
【问题描述】:

当我在结构中创建一个 char 指针时,我可以只为该值分配一个字符串,它工作正常。当我尝试对 int 数组执行类似操作时,我会收到编译警告,这可能是由于我正在尝试执行的操作的语法不正确。数据的值在程序的整个生命周期中都是静态的:

struct structure
{
    char *name;
    int *data[]; //Likely the issue
};

struct structure value = {
    "Some name",
    {0, 1} //Error is here
};

每当我尝试初始化值对象时,我都会收到一个关于从没有类型转换的整数创建指针的编译错误。我的假设是该值需要一个指针,所以我首先要求的是错误的值。

我的问题是,如何在结构中声明一个 int 数组,这样我的值对象声明仍然有效?

【问题讨论】:

  • int *数据;为什么是括号?
  • @RSon1234 我试图将它声明为“指向数组的指针”,这样我就可以在值对象内部简单地声明一个数组,而不必在程序中使用 malloc初始化。我不认为 malloc 是必需的,因为数组的实际长度在编译之前是已知的。
  • @DavidBowling 数组长度因结构的实例而异,但对于该结构的一个实例来说它是静态的,并且在整个运行时都不会改变。我没有将那部分包含在 OP 中。这就是为什么我问,“我如何在结构中声明一个 int 数组,以便我的值对象声明仍然有效?”
  • @RSon1234 数组不是常量指针。

标签: c arrays pointers integer structure


【解决方案1】:
  1. 您不能只为未初始化的/空指针赋值;您需要使用malloc 为它们分配内存。

  2. 只要定义为int *data即可。

【讨论】:

  • 它们之间有一个/,这意味着它们是两个不同的东西
【解决方案2】:

结构中带有[] 的符号是“灵活数组成员”(FAM)。您的结构包含int * 类型的FAM,因此数组中的值是指向int 的指针。你说你想要一个int 的数组;那将是int data[];

根据 C 标准,您不能使用 FAM 初始化结构的 FAM 部分。您可以初始化结构的其余部分,但 FAM 组件将为空,并且无法将 FAM 组件添加到该结构。

你需要做这样的事情——为数组动态分配结构和空间:

struct structure
{
    char   *name;
    size_t  size;
    int     data[];
};

int data[] = { 0, 1 };

struct structure *value = malloc(sizeof(*value) + sizeof(data));

if (value != 0)
{
    value->name = "Some name";
    value->size = sizeof(data) / sizeof(data[0]);
    memcpy(value->data, data, sizeof(data));
    …code using value…
    free(value);
}

我将size 成员添加到结构中,因为使用它的代码需要以某种方式知道数组的大小。

以下代码演示了 GCC 允许初始化 FAM,除非您告诉它遵循标准:

#include <stddef.h>

struct structure
{
    char   *name;
    size_t  size;
    int     data[];
};

struct structure value = { "Some name", 2, { 0, 1 } };

GCC(在运行 macOS Sierra 10.12.3 的 Mac 上使用 6.3.0 测试)允许初始化,除非你告诉它是迂腐的:

$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror           -c fam13.c
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -pedantic -c fam13.c
fam13.c:10:44: error: initialization of a flexible array member [-Werror=pedantic]
 struct structure value = { "Some name", 2, { 0, 1 } };
                                            ^
fam13.c:10:44: note: (near initialization for ‘value.data’)
cc1: all warnings being treated as errors
$

它与函数内的变量定义类似。

【讨论】:

    【解决方案3】:

    你可以写:

    struct structure
    {
        char *name;
        int *data;
    };
    
    struct structure value = {
        "Some name",
        (int[]){0, 1}
    };
    

    当然,当您稍后访问它时,您还需要使用其他方法来了解数组中实际有多少整数。

    请注意,如果此代码出现在函数内部,则 int 数组将在函数返回时停止存在。 (与字符串文字不同)

    【讨论】:

    • 这正是我想要的。略微增加了结构的复杂性,但我不必在程序启动时进行 malloc。我知道有一种方法可以在没有 malloc 的情况下执行此操作,因为我正在使用预先知道的值来执行此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-11-22
    • 2020-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多