我想使用类似于chux
建议的联合数组
union {
uint8_t u8[12];
uint16_t u16[6];
} *array_u;
array_u = calloc(1, sizeof *array_u);
assert(array_u);
printf("array_u->u8[0] = %" PRIu8 "\n", array_u->u8[0]);
array_u->u16[0] = 1234;
printf("array_u->u16[0] = %" PRIu16 "\n", array_u->u16[0]);
...
来源:Is it okay to store different datatypes in same allocated memory in C?
我想将它用作不同文件需要访问它的全局数组。所以我尝试了globals.h
:
extern union {
uint8_t u8[12];
uint16_t u16[6];
} *array_u;
我想在此文件memory.c
中分配并释放它:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include "globals.h"
void allocate_array_u(void){
array_u = calloc(1, sizeof *array_u);
}
我很遗憾地收到error LNK2001: unresolved external symbol array_u
我该如何解决?
解决方案:
我忘了在main.c
或memory.c
:
array_u_t *array_u;
答案 0 :(得分:6)
除了将array_u
声明为extern
之外,您还需要定义变量。 extern
只是说要在其他地方找到定义。该定义需要存在于某个地方。
请尝试以下操作。
按如下方式更改globals.h
:
typedef union {
uint8_t u8[12];
uint16_t u16[6];
} array_u_t;
extern array_u_t *array_u;
在array_u
中定义memory.c
,如下所示:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
#include "globals.h"
array_u_t *array_u; // <---------------- definition
void allocate_array_u(void){
array_u = calloc(1, sizeof *array_u);
}
答案 1 :(得分:1)
您在包含array_u
但位于其中的每个源文件中将globals.h
声明为外部符号?每个变量都必须在某处定义;即未声明为external
和可选的初始化。
选择最合适的C文件并写入:
union {
uint8_t u8[12];
uint16_t u16[6];
} *array_u = NULL;
最好使用typedef
来获取变量array_u
的联合类型的名称,以避免定义它两次。
写入globals.h
:
typedef union {
uint8_t u8[12];
uint16_t u16[6];
} array_u_type;
extern array_u_type *array_u;
写入其中一个C文件(例如memory.c
):
#include "globals.h"
array_u_type *array_u = NULL;
在上面的示例array_u_type
中替换为您喜欢的新数据类型的任何名称。
答案 2 :(得分:1)
建议给联盟一个“标签”名称。
union myunion
{
uint8_t u8[12];
uint16_t u16[6];
};
然后在单独的语句中声明一个指向union的指针的实例:
union myunion *array_u = NULL;
然后将指向联合的指针设置为值:
array_u = calloc(1, sizeof union myunion);
注意:调用assert()
不会告诉用户出现了什么问题,并且在生产代码中选择不当。
相反,建议:
if( NULL == array_u )
{ // then calloc failed
perror( "calloc for instance of union myunion failed: );
exit( EXIT_FAILURE );
}
// implied else, calloc successful
注意:在左侧放置文字“NULL”,因此键入错误(如键入=
而不是==
)将被编译器捕获,而不是花费数小时和数小时来查找'糟糕'。