为什么在C中我的动态分配的struct数组不工作?

时间:2013-04-26 04:13:28

标签: c arrays struct dynamic-allocation

我一直在尝试创建一个动态分配的结构类型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文件中有一个函数,用于将这些struct对象添加到数组中,供文件中的其他方法使用:

    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 *'

2 个答案:

答案 0 :(得分:5)

你不能像这样分配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来设置值,然后您需要确保在第一次使用它之前分配它。

答案 1 :(得分:1)

我建议使用memcpy

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