【问题标题】:How to properly allocate enough memory (malloc) when creating a new struct in C?在 C 中创建新结构时如何正确分配足够的内存(malloc)?
【发布时间】:2020-03-24 04:23:24
【问题描述】:

鉴于下面的结构,我正在创建一个函数,该函数接收 person_in_queueposition_num 并分配一个新的 queue_t 结构,该结构添加到 queue_t 结构列表的末尾,由第一个参数。

typedef struct queue {
  int position_num;
  char *person_in_queue;

  struct queue *next_in_line;
} queue_t;

我的代码是这样写的:

queue_t *add_to_queue(queue_t *input_queue, char *person_in_queue, int position_num) {

  input_queue = malloc(sizeof(queue_t));
  assert(input_queue != NULL);

  input_queue->position_num = position_num;
  input_queue->person_in_queue = (char *) malloc((strlen(new_text) + 1) * sizeof(char));
  assert(input_queue->person_in_queue != NULL);

  strcpy(input_queue->person_in_queue, person_in_queue);
  return input_queue;

}

所述代码可以编译,但是,我被告知我的代码失败了,因为分配的内存比预期的要少。目前,我不确定我在哪里出错了。请注意,我需要使用malloc()

非常感谢!

【问题讨论】:

  • 好吧,快速浏览一下:input_queuequeue_t * 类型,但你正在做 malloc(sizeof(operation_t))。除此之外:您将 input_queue 作为参数并立即将其覆盖为函数中的第一件事,然后返回它。这没有多大意义,并且完全不需要将其作为参数传递。
  • 这个问题被标记为 C。不要在 C 中强制转换 malloc()。它可能会导致错误。强制转换 malloc() 是 C++ 的习惯。 stackoverflow.com/questions/605845/…
  • 也不需要使用* sizeof(char)。 C 标准将 char 指定为一个字节,因此 sizeof(char) 始终返回 1。
  • 你越来越近了——但是注意:当你编辑你的问题时,不要删除原来的问题.而是在问题结束时添加 更新或编辑。为什么?因为删除原始问题的某些部分将呈现与问题的已删除部分相关的所有 cmets 和答案——毫无意义。
  • 你不能断言 malloc 没有返回 NULL,因为 malloc 可能返回 null。你需要检查它,使用assert不是错误检查。

标签: c struct malloc typedef deep-copy


【解决方案1】:

sizeof 是 C 中的运算符,不是函数,但括号是评估类型所必需的。

要为结构分配内存,请使用类型的大小。

input_queue = malloc(sizeof (queue_t));

或使用取消引用的指针或对象大小(此处不需要括号)。

input_queue = malloc(sizeof *input_queue);

【讨论】:

  • 在获取类型的大小时需要使用括号......您可以通过指定类型的对象来避免不匹配,即*input_queue
  • 我的记忆已经崩溃了。 (我习惯使用对象大小[deerreferenced pointer]。
【解决方案2】:

我被告知我的代码失败了,因为分配的内存比预期的少。

那一定是malloc((strlen(new_text) + 1) * sizeof(char))。显然new_text 是一个全局字符串,与person_in_queue 没有可见的连接,后者将被复制。将呼叫更改为malloc(strlen(person_in_queue) + 1)

在 C 中创建新结构时如何正确分配足够的内存(malloc)?

除此之外,分配基本上没问题,但正如 Marco Bonelli 所说,您将 input_queue 作为参数并立即覆盖它……这没有多大意义……如果input_queue 最初是NULL,则返回分配的queue_t 对象是有意义的,否则传递的input_queue 不变。这可以通过将函数主体的前两个语句更改为

来完成
    queue_t *head_queue = input_queue, **pr = &input_queue;
    while (*pr) pr = &(*pr)->next_in_line;  // find end of list
    *pr =   // link new struct to list
    input_queue = malloc(sizeof(queue_t));
    assert(input_queue != NULL);
    input_queue->next_in_line = NULL;       // don't forget to initialize!

和返回语句到

    return head_queue ? head_queue : input_queue;

- 前者也正确设置了链接指针next_in_line

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-11-08
    • 1970-01-01
    • 1970-01-01
    • 2019-11-18
    • 2014-04-24
    • 2018-04-27
    • 2015-11-09
    • 2023-04-05
    相关资源
    最近更新 更多