[英]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.