【问题标题】:Why isn't my dynamically allocated struct array in C working?为什么我在 C 中动态分配的结构数组不起作用?
【发布时间】:2013-04-20 04:01:42
【问题描述】:

我一直在尝试创建一个动态分配的结构类型 label 的数组,但失败得很惨。在我的 .h 文件中,我有:

    typedef struct _label {
            char name[256];
            char type[256];
            int address;
} label;

在我的 .c 文件中,我在顶部有这个:

    label* allLabels = (label*) malloc(sizeof(label) * 10); // line 10
    int arrayIndex = 0;

最后,我在同一个 .c 文件中有一个函数,用于将这些结构对象添加到数组中,以供文件中的其他方法使用:

    void addLabel(char line[], char type[], int addr) {
            label database;
            database.name = line; // line 805
            database.type = type; // line 806
            database.address = addr;
            allLabels[arrayIndex] = database;
            arrayIndex++;
        }

基本上我只想拥有一组可访问的标签。有人可以帮我理解我做错了什么吗?

我得到了这些错误,我也没有忘记任何必要的#include 语句:

formatBuilder.c:10:3: error: initializer element is not constant
formatBuilder.c: In function 'addLabel':
formatBuilder.c:805:18: error: incompatible types when assigning to type 'char[256]' from type 'char *'
formatBuilder.c:806.18: error: incompatible types when assigning to type 'char[256]' from type 'char *'

【问题讨论】:

  • 数组不是指针。您不能使用= 运算符为数组分配新值。
  • 代码中的database 是什么?
  • database 是我的标签对象的名称

标签: c arrays struct dynamic-allocation


【解决方案1】:

你不能分配给char这样的数组,你需要一个字符串操作,比如:

strcpy (database.name, line);  // or "->" if database is pointer

(最好事先检查长度以确保没有缓冲区溢出,或者根据您的需要使用更安全的功能)。

在 C 中从malloc 转换返回值也是一种不好的形式,因为它可以隐藏某些细微的错误。如果您的代码也必须在 C++ 中编译,这是可以接受的,但您只需要确保您在范围内拥有正确的原型。


就初始化错误而言,我怀疑您有文件级别的声明(在任何函数之外)。这意味着您不能使用函数调用来初始化它,因为它具有静态存储持续时间并且希望在任何代码运行之前进行设置。

您可以这样解决那个问题:

// At file level:

label* allLabels = NULL;

// In your function:

void addLabel(char line[], char type[], int addr) {
    if (allLabels == NULL) {
        allLabels = malloc (sizeof(label) * 10);
        if (allLabels == NULL) {
            // malloc failed, do something to recover.
        }
    }
    // And we don't need local storage here, hit the array directly.

    strcpy (allLabels[arrayIndex].name, line);
    strcpy (allLabels[arrayIndex].type, type);
    allLabels[arrayIndex].address = addr;
    arrayIndex++;
}

这使用常量初始化器NULL 来设置值,然后您只需确保在第一次使用它之前分配它。

【讨论】:

  • 啊,太棒了!这修复了 805 和 806 的错误。我仍然有初始化程序错误,但我更近了一步。谢谢!!这是由我的 malloc 铸造引起的吗?还是完全是另外一回事?
  • @Laurence,对不起,实际上并没有看到那一点。更新的答案也涵盖了这一点。
【解决方案2】:

我建议使用memcpy

memcpy(&allLabels[arrayIndex], &database, sizeof(label));

【讨论】:

  • 感谢您的建议!
猜你喜欢
  • 2020-04-26
  • 2011-03-21
  • 2021-02-23
  • 2021-08-19
  • 2014-08-22
  • 2012-05-17
  • 2012-01-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多