为struct数组分配内存(在头文件中定义)

时间:2014-03-19 11:37:11

标签: c arrays struct

我真的不知道如何为标头中定义的struct数组正确分配内存。 标题代码如下所示:

header.h

typedef struct _Transform Transform;

header.c

struct _Transform{
    char c;
    //the actual operation which is an union
    Operation o;
};

我的主程序应该做这样的事吗?

program.c

#include "header.h"

Transform **transform = calloc( MAX_NO_OF_TRANSFORMS, sizeof( Transform* ) );
if(!transform ) {
    perror("Error allocating memory for transform");
    exit(EXIT_FAILURE);
}
for(i = 0; i < MAX_NO_OF_TRANSFORMS; i++)
    transform[i] = calloc( 1, sizeof( Transform* ) );

如果是这样,我该怎么称呼呢?我尝试拨打

时出错
transform[0].c = 'a';

顺便说一句,标题正确链接并正常工作。 谢谢!

3 个答案:

答案 0 :(得分:2)

如果没有范围内的结构定义,您将永远无法在program.c中声明数组。头文件没有提供足够的信息来使编译器知道Transform的大小,因此您无法在program.c中声明它的数组。

指向Transform的指针的分配是有效的,因为编译器不需要知道Transform的大小,因为指向的对象本身就是指针。

将结构定义移动到头文件中。换句话说,header.h应为:

<强> header.h

struct _Transform{
    char c;
    //the actual operation which is an union
    Operation o;
};

typedef struct _Transform Transform;

现在,在program.c中,您可以声明一个静态分配的数组:

Transform transform[MAX_NO_OF_TRANSFORMS];

您的代码中无需使用动态分配的内存;鉴于我们在评论部分进行的讨论,这是过度的,完全没必要。

<强>更新

由于你似乎对这类东西不熟悉,我会给你另一个提示:总是在头文件中使用include guard,以避免由于多次包含而导致编译器出现奇怪的错误。例如,如果您在header1.h中包含header2.hprogram.c,并且header2.h已包含header1.h,那么在编译program.c时会出现多个定义错误(它好像你包含了两次相同的文件)。包括警卫防范这一点。典型用法如下:

<强> header.h

#ifndef TRANSFORM__STRUCT__HEADER
#define TRANSFORM__STRUCT__HEADER
struct _Transform{
    char c;
    //the actual operation which is an union
    Operation o;
};

typedef struct _Transform Transform;
#endif

这是一种广泛使用的技术。基本上,它通过在第一次包含文件时定义预处理器符号来工作 - 如果再次包含该文件,#ifndef将评估为false,并且不会包含任何内容。

答案 1 :(得分:0)

您的代码存在一些问题。首先,以下声明

transform[i] = calloc(1, sizeof(Transform *));

分配内存以保存指向Transform对象的指针,而不是Transform对象本身。

其次,sizeof在编译期间运行,但可变长度数组对象除外。文件Transform范围内的类型名称program.c是不完整类型,因为如果没有在链接阶段解析的定义,则无法确定其大小。您应该将结构定义移动到header.h文件。

// header.h

typedef struct _Transform {
    char c;
    //the actual operation which is an union
    Operation o;
} Transform;

此外,您应该修改program.c

// program.c

// dynamically allocate an array to hold pointers to Transform objects

Transform **transform = calloc(MAX_NO_OF_TRANSFORMS, sizeof *transform);
if(!transform) {
    perror("Error allocating memory for transform");
    exit(EXIT_FAILURE);
}



for(i = 0; i < MAX_NO_OF_TRANSFORMS; i++) {
    // allocate memory to hold Transform objects and make the array element 
    // point to it. You can also replace **transform with *transform[i] in 
    // the calloc call.

    transform[i] = calloc(1, sizeof **transform);

    // check for NULL
    if(transform[i] == NULL) {
        perror("Error in allocating memory");
        // handle it
    }
}

答案 2 :(得分:0)

塞巴斯蒂安,

此:

transform[i] = calloc( 1, sizeof( Transform* ) );

应改为:

transform[i] = calloc( 1, sizeof( Transform ) );

你需要分配足够的内存来存储记录 - 第一种方法,你只需为指向Transform的指针分配足够的内存。