导致此 C 运行时错误的原因是导致数组中间出现垃圾数字

问题描述 投票:0回答:1

我是一名初级 C 开发人员,在我的 C 程序中遇到一个奇怪的错误后,我完全被难住了。 这是我遇到问题的代码:

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

void resize(int *array, int newsize) {
  int old_size = sizeof(*array);

  int *temp = malloc(old_size);
  if (temp == NULL) {
    printf("Failed to allocate new list memory. Fatal error - crash.\n");
    exit(EXIT_FAILURE);
  }

  for (int i = 0; i < old_size; i++) {
    temp[i] = array[i];
  }

  array = malloc(sizeof(int) * newsize);
  if (array == NULL) {
    printf("Failed to allocate new list memory. Fatal error - crash.\n");
    exit(EXIT_FAILURE);
  }

  for (int i = 0; i < old_size; i++) {
    array[i] = temp[i];
  }

  for (int i = 0; i < newsize; i++) {
    array[i] = 0;
  }

  free(temp);
}

int main() {
  int *arr = malloc(sizeof(int) * 3);
  if (arr == NULL) {
    printf("Failed to allocate new list memory. Fatal error - crash.\n");
    exit(EXIT_FAILURE);
  }

  arr[0] = 1;
  arr[1] = 2;
  arr[2] = 3;

  printf("Original array:\n");
  for (int i = 0; i < 3; i++) {
    printf("index %d element %d\n", i, arr[i]);
  }

  printf("\nNew array:\n");

  int newsize = 30;
  resize(arr, newsize);

  for (int i = 3; i < newsize; i++) {

    arr[i] = i + 1;
  }

  for (int i = 0; i < newsize; i++) {
    printf("index %d element %d\n", i, arr[i]);
  }

  free(arr);

  return 0;
}

和输出:

./a.out
Original array:
index 0 element 1
index 1 element 2
index 2 element 3

New array:
index 0 element 1
index 1 element 2
index 2 element 3
index 3 element 4
index 4 element 5
index 5 element 6
index 6 element 7
index 7 element 8
index 8 element 1701080681
index 9 element 540549240
index 10 element 1835363429
index 11 element 1953391981
index 12 element 892940576
index 13 element 892351545
index 14 element 168441140
index 15 element 16
index 16 element 17
index 17 element 18
index 18 element 19
index 19 element 20
index 20 element 21
index 21 element 22
index 22 element 23
index 23 element 24
index 24 element 25
index 25 element 26
index 26 element 27
index 27 element 28
index 28 element 29
index 29 element 30

程序按预期工作,除了在索引 8-14 处显示垃圾数字之外。 有趣的是,意外的数字始终位于索引 8-14(无论数组长度如何)并且始终是相同的数字。

这是我第一篇关于堆栈溢出的帖子,我之所以发这个帖子只是因为我非常困惑, 感谢任何帮助,谢谢!

我尝试检查(现有)值移入和移出临时数组的情况。数字保持不变。

c runtime-error
1个回答
0
投票

祝你学习 C 之旅顺利。我在这里注意到了一些问题,我想我对你的问题有一个解释。


这部分不是导致您出现问题的原因,但您应该注意这一点。

int old_size = sizeof(*array);
int *temp = malloc(old_size);

这会分配 4 个字节的内存,因为这是一个整数的大小。它无法告诉您数组的长度。 C 不会在运行时存储该信息。您需要将其作为额外参数传递到调整大小函数中。然后,您尝试访问不属于 temp 的内存,因为它只有一个整数的空间。


我认为问题所在。

array = malloc(sizeof(int) * newsize);

您从未真正释放原始数组,因此这里发生了内存泄漏。但更重要的是,这不会改变主函数中的指针。这一点都没有改变。实际上,您已经做到了这一点:

void foo(int x) {
    x = 5;
}

void main() {
    int x = 3;
    foo(x);
    // x will still be 3 here
}

现在,由于主函数中的

arr
变量未更改,因此循环正在访问不属于
arr
数组的内存。因此内存分配器仍然能够将该内存提供给其他对
malloc
的调用。当您调用
printf
函数时,它开始使用
arr
数组后面的一些字节,并且您可以在 for 循环中访问这些字节。

解决此问题的方法是更改您的

resize
函数以采用
**int
而不是
*int

void resize(int **array, int newsize) {
  free(*array);

  *array = malloc(sizeof(int) * newsize);
  if (*array == NULL) {
    printf("Failed to allocate new list memory. Fatal error - crash.\n");
    exit(EXIT_FAILURE);
  }

  for (int i = 0; i < newsize; i++) {
    (*array)[i] = 0;
  }
}

此外,您可能已经知道这一点,但以防万一您不知道,标准库中已经有一个名为

realloc
的函数。

arr = realloc(arr, sizeof(int) * newsize);
© www.soinside.com 2019 - 2024. All rights reserved.