繁体   English   中英

如何访问联合中的结构并在 c 中指向它们

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM