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

时间:2021-12-24 03:13:29

I have been trying to create a dynamically allocated array of struct type label and have been failing miserably. In my .h file, I have:

我一直在尝试创建一个动态分配的struct类型标签数组,并且一直在惨败。在我的。h文件中,我有:

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

and in my .c file, I have this at the top:

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

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

and finally, I have a function in the same .c file that is meant to add these struct objects to the array to be used by other methods in the file:

最后,我在相同的.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++;
        }

Basically I just want to have a collection of accessible labels. Can someone help me understand what I'm doing wrong?

基本上,我只是想要一个可访问标签的集合。有人能帮我理解我做错了什么吗?

I get these errors, and I haven't forgotten any of the necessary #include statements either:

我有这些错误,我也没有忘记任何必要的#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 个解决方案

#1


5  

You can't assign to char arrays like that, you need one of the string operations, such as:

您不能像那样分配char数组,您需要一个字符串操作,例如:

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

(preferably checking the length beforehand to ensure no buffer overflow, or using a safer function depending on your needs).

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

It's also bad form to cast the return value from malloc in C since it can hide certain subtle errors. It's acceptable if your code has to also compile in C++ but you just need to ensure you have the correct prototype in scope.

将malloc的返回值转换为C也很糟糕,因为它可以隐藏某些细微的错误。如果您的代码也必须使用c++编译,这是可以接受的,但是您只需要确保在范围内拥有正确的原型。


In terms of the initialisation error, I suspect that you have the declaration at file level (outside of any function). This means you can't use a function call to initialise it since it has static storage duration and wants to be set before any code runs.

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

You can get around that problem thus:

你可以这样解决这个问题:

// 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++;
}

This uses a constant initialiser NULL to set the value and you then just need to ensure it's allocated before the first time you use it.

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

#2


1  

I suggest to use memcpy.

我建议使用memcpy。

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

#1


5  

You can't assign to char arrays like that, you need one of the string operations, such as:

您不能像那样分配char数组,您需要一个字符串操作,例如:

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

(preferably checking the length beforehand to ensure no buffer overflow, or using a safer function depending on your needs).

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

It's also bad form to cast the return value from malloc in C since it can hide certain subtle errors. It's acceptable if your code has to also compile in C++ but you just need to ensure you have the correct prototype in scope.

将malloc的返回值转换为C也很糟糕,因为它可以隐藏某些细微的错误。如果您的代码也必须使用c++编译,这是可以接受的,但是您只需要确保在范围内拥有正确的原型。


In terms of the initialisation error, I suspect that you have the declaration at file level (outside of any function). This means you can't use a function call to initialise it since it has static storage duration and wants to be set before any code runs.

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

You can get around that problem thus:

你可以这样解决这个问题:

// 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++;
}

This uses a constant initialiser NULL to set the value and you then just need to ensure it's allocated before the first time you use it.

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

#2


1  

I suggest to use memcpy.

我建议使用memcpy。

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