【问题标题】:Append function for C with dynamic memory allocation具有动态内存分配的 C 附加函数
【发布时间】:2019-09-04 21:24:51
【问题描述】:

this question 之后,我正在尝试修改this blog post 中提供的代码,以使用动态内存分配创建append 函数。这是我目前所拥有的:

#include <stdio.h>
#include <stdlib.h>

typedef struct intlist_ {
  int size;
  int* list;
} intlist;

void append(intlist* arr, int value){
  realloc((*arr).list, sizeof((*arr).list) + sizeof(int));
  (*arr).size = (*arr).size + 1;
  (*arr).list[(*arr).size -1] = value;
}

int main() {

  intlist arr;
  arr.size = 4;
  arr.list = malloc(arr.size * sizeof(int));

  arr.list[0] = 0;
  arr.list[1] = 5;
  arr.list[2] = 3;
  arr.list[3] = 64;

  append(&arr, 12);

  for (int ii = 0; ii < arr.size; ii++)
    printf("%d, ", arr.list[ii]);

  free(arr.list);
  return 0;
}

但是我得到的结果是错误的:

clang 版本 7.0.0-3~ubuntu0.18.04.1 (tags/RELEASE_700/final) main.c:10:3:警告:忽略用声明的函数的返回值 'warn_unused_result' 属性 [-Wunused-result] realloc((*arr).list, sizeof((*arr).list) + sizeof(int)); ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~ 生成 1 个警告。 0, 5, 3, 64, 0, 5, 3, 64, 12,

我正在使用this online compiler 进行测试,您还可以在其中看到上述代码的最新版本。如果您能帮助我知道我的错误在哪里以及如何解决它,我将不胜感激。提前感谢您的支持。

P.S.您可以在this Gist这里获得代码的最终版本。

【问题讨论】:

  • 为什么你认为结果是错误的?我试图编译它,我得到了正确的结果。
  • @EmirG。你说的对。我在原来的帖子中犯了一个可怕的错误,忘记评论第一个 for 循环。 :( 耻辱。但是我收到的警告仍然是一个问题。

标签: c arrays append dynamic-memory-allocation


【解决方案1】:

关闭,但是:

  1. sizeof((*arr).list) 不会给你数组的大小。相反,它会给你int* 的大小。
  2. realloc 使原始指针无效,继续使用它是未定义的行为。请改用返回值。

因此,更改您的 realloc 行以使用存储的列表大小,并使用返回值更新指针:

(*arr).list = realloc((*arr).list, ((*arr).size + 1) * sizeof(int));

其他提示:

  • ptr-&gt;(*ptr). 相同,但更易于阅读。我建议将您所有的 (*arr).size(*arr).list 更改为 arr-&gt;sizearr-&gt;list
  • realloc 和它的兄弟们一样,不能保证一定会成功。您应该检查 null 的返回值以捕获错误。
  • clang 警告(通常情况下)很有帮助 - 检查返回值可以解决几个问题。

【讨论】:

  • 谢谢。看来original post 也是错误的。但是,您的解决方案并未删除警告。 ?
  • realloc((*arr).list, ((*arr).size + 1) * sizeof(int)); --> 不。重新分配的值被丢弃。只有 UB 才能工作。
  • @chux 你能详细说明一下吗?它似乎工作正常。
  • @Foad 许多重新分配不使用新的内存区域,到目前为止,您的代码都依赖于此。继续打电话给你/这个append(),代码会失败。
【解决方案2】:
  • 分配的大小错误。 sizeof((*arr).list) 是指针的大小,而不是 int

  • 未使用返回值。 realloc() 返回新指针。

  • 没有NULL检查

与其使用容易出错的ptr = some_alloc(sizeof(type) * n),不如使用 ptr = some_alloc(sizeof *ptr * n)


void append(intlist *arr, int value){
  int *new_ptr = realloc(arr->list, sizeof *(arr->list) * (arr->size + 1u));
  if (new_ptr == NULL) {
    fprintf(stderr, "Out of memory\n");
    exit (EXIT_FAILURE);
  }
  arr->list = new_ptr;
  arr->list[arr->size] = value;
  arr->size++;
}

【讨论】:

  • 非常感谢。我不明白*(arr-&gt;list)1u。我也认为arr-&gt;list[arr-&gt;size] = value; 应该是arr-&gt;list[arr-&gt;size - 1] = value; 不是吗?
  • @Foad sizeof *(arr-&gt;list)arr-&gt;list 指向的大小。使用int* list;,指向int 中的类型指针。
  • 顺便说一句,new_arr == NULL 应该更改为 new_ptr == NULL
  • @Foad 分配采用size_t 参数,一些无符号类型。 arr-&gt;size + 1u 加 1,使用 unsigned 数学而不是 int math 来形成尺寸乘积。
  • @Foad "我也认为 arr->list[arr->size] = value; 应该是 arr->list[arr->size - 1] = value; 不应该?”。不。实际上你想要arr.list[4] = 12; 这个代码在增加.size 之前进行赋值。
猜你喜欢
  • 2011-11-13
  • 2013-10-31
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
  • 2013-11-10
  • 1970-01-01
  • 2017-03-16
  • 2015-12-07
相关资源
最近更新 更多