【问题标题】:Adding integers to a dynamic array in C, memory problem将整数添加到C中的动态数组,内存问题
【发布时间】:2021-05-20 09:04:49
【问题描述】:

我在将整数添加到动态数组读取器时遇到问题,所以下面代码中的第二个函数。为什么输出中添加的数字看起来很奇怪?我猜是内存问题,不知怎么分配新内存不正确。

int *create_dyn_array(unsigned int n)
{
    
    int *array = malloc(n * sizeof(*array));

    for (size_t i = 0; i < n; i++) {
        scanf("%d", &array[i]);
    }

    return array;
}

int *add_dyn_array(int *arr, unsigned int num, int newval)
{

    int *temp = NULL;

    temp = realloc(arr, (num + 1)*sizeof(int));
    arr = temp;

    int *newarray = arr;
    while(*arr) {
        arr++;
    }

    int testarray[1];
    int *ptr = testarray;
    int j = 1;
    while (j > 0) {
        *ptr = newval;
        ptr++;
        j--;
    }
    ptr = testarray;

    while(*ptr) {
        *arr++ = *ptr++;
    }

    return newarray;
}

void printarray(const int *array, int size) {
    printf("{ ");
    for (int i = 0; i < size; ++i) {
        printf("%d, ", array[i]);
    }
    printf(" }\n");
}

int main()
{
    int *array = create_dyn_array(5);
    printarray(array, 5);
    
    array = add_dyn_array(array, 5, 10);
    printarray(array, 6);
    
    array = add_dyn_array(array, 6, 100);
    printarray(array, 7);
    
    array = add_dyn_array(array, 7, 1000);
    printarray(array, 8);
    
    return 0;
}

realloc 逻辑有什么问题?

【问题讨论】:

  • 那个仪式应该做什么?添加应该只是realloc(...);temp[num]=newval; return temp;,不需要更多。也就是说,如果您尝试将 newval 添加到数组的末尾。如果这应该做其他事情,请在问题中解释。
  • 如果您尝试添加多个元素并用 newval 填充它们,您需要知道以前的大小和新的大小。您不能假设 realloc 添加的额外元素最初会具有任何特定值。
  • 请不要添加文字图片。改为将其作为文本添加到您的问题中。

标签: arrays c pointers memory dynamic


【解决方案1】:

这就是 realloc 的工作原理:

新对象的内容应与释放前旧对象的内容相同,直到新旧大小中的较小者。

无需手动复制任何内容。整个函数可以简化为:

int *add_dyn_array(int *arr, unsigned int num, int newval)
{
  int *temp = realloc(arr, (num + 1)*sizeof(int));
  if(temp == NULL)
  { 
    /* optionally handle errors in some way */
    exit(EXIT_FAILURE);
  }
  temp[num] = newval;

  return temp;
}

但请注意,一次重新分配一个项目非常效率低下。

【讨论】:

  • 效率取决于实现。在我的 GNU/Linux x84-64 系统上,一个从 1 到 1000000 的简单循环将相同的块重新分配到循环索引计数器指定的长度只会改变返回的指针 20 次。
  • @IanAbbott 当然可以,但要抱最好的希望,做好最坏的准备。
  • @IanAbbott 你也写到内存了吗?如果没有,那么操作系统可能会优化实际分配并在实际需要内存之前避免这样做。
  • @Lundin 我忽略了写入内存,但是在重新分配之后稍微调整写入块的最后一个字节后,重新分配块的次数没有变化(尽管有时会重新分配 20 次,有时会重新分配 24 次)。
  • 感谢您的帮助。下次我只删除 3/4 的代码,也许它马上就可以工作了,呵呵。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-15
  • 1970-01-01
  • 2021-12-05
  • 1970-01-01
  • 2022-11-17
  • 1970-01-01
相关资源
最近更新 更多