我真的不知道如何为标头中定义的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';
顺便说一句,标题正确链接并正常工作。 谢谢!
答案 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.h
和program.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的指针分配足够的内存。