[英]How to access structs in Unions and point to them in c
我必须基于这个struct
在 c 中实现一个构造函数:
struct Node {
char name[MAX_NAME_LEN + 1];
NodeType type;
union {
struct {
Entry* entries; // list of directory entries
} dir;
struct {
void* contents; // any binary data of the given length
int length;
} file;
};
};
现在我想为file
构建一个构造函数,指向内容并以字节为单位保存长度,但不知何故我不知道该怎么做......
这是我的尝试:我知道我必须为此分配空间,但我该如何制作这个指针呢?
Node* new_file(char* name) {
Node* ptr_file = xmalloc(sizeof(Node));
ptr_file->name;
return NULL;
}
typedef struct {... } Node
才能编译代码。ptr_file->dir.entries
或ptr_file->file.contents
。ptr_file->entries;
.请注意,在 ISO 9899:2011 版本的语言中,匿名结构/联合被添加到 C 语言中,因此您需要使用相当现代的编译器才能使用它们。
作为旁注, void*
可能没有任何意义。 我认为您正在尝试做的是:
#include <stdint.h>
typedef struct {
char name[MAX_NAME_LEN + 1];
NodeType type;
union {
struct {
Entry* entries; // list of directory entries
};
struct {
uint8_t contents [sizeof(Entry)]; // use to inspect raw data
int length; // probably not needed
};
};
} Node;
对于Node* new_file(char* name)
, Node
尚未定义。 代码需要typedef struct Node Node;
等等。
这项任务的一大挑战是可能会出现许多潜在的错误:文件名太长、内存分配失败、fopen 打开失败、读取失败、文件太长……
int length;
应该是size_t length;
因为文件可能比INT_MAX
长,但适合分配。
new_file(char* name)
看起来应该读取一个文件。 让我们创建一个辅助函数,因为需要不同程度的健壮性。 以下通常“有效”但属于技术 UB(寻找二进制文件的末尾)。 根据需要进行调整。
说明性的、未经测试的代码:
// The below does _not_ return a null character appended string,
// just the data in the file.
void *alloc_file(const char *file_name, size_t *size) {
*size = 0;
FILE *binary_stream = fopen(file_name, "rb");
if (binary_stream == NULL) {
return NULL;
}
long offset = fseek(binary_stream, SEEK_END);
rewind(binary_stream);
if (offset == -1 || (unsigned long) offset > SIZE_MAX) {
fclose(binary_stream); // Trouble or file too long
return NULL;
}
size_t file_size = (size_t) offset;
void *buf = malloc(file_size) {
fclose(binary_stream);
return NULL;
}
if (fread(buf, 1, file_size, binary_stream) != file_szie) {
fclose(binary_stream);
free(buf);
return NULL;
}
*size = file_size;
fclose(binary_stream);
return buf;
}
现在new_file
更容易了。
// Better as: Node* new_file(const char* name)
Node* new_file(char* name) {
if (strlen(name) >= MAX_NAME_LEN) {
return NULL // name too long
}
// Allocate to the size of the referenced object, not type.
Node* ptr_file = malloc(sizeof ptr_file[0]);
if (ptr_file == NULL) {
return NULL;
}
strcpy(ptr_file->name, name);
ptr_file->type = NodeType_file; // Some constant (OP has not shown yet).
size_t size = 0;
ptr_file->file.contents = alloc_file(name, &size);
if (ptr_file->file.contents == NULL || size > INT_MAX) {
free(ptr_file->file.contents);
free(ptr_file);
return NULL;
}
ptr_file->length = (int) size;
return ptr_file;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.