You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C运行时错误致数组中间出现垃圾值的原因排查

问题分析与修正

你的代码存在两个核心错误,直接导致了内存越界和未定义行为:

1. 错误的原数组长度计算

resize函数里的int old_size = sizeof(*array);完全错误。*array是单个int类型,sizeof(*array)得到的是单个int的字节数(通常是4),而不是原数组的元素个数(3)。这会导致:

  • 你只分配了4字节的临时内存(即1个int的空间),却循环4次复制数据,越界访问temp数组,触发未定义行为。
  • 即使后续内存分配正确,也会错误地复制4个元素,而不是原数组的3个。

2. 指针传值导致的无效修改

C语言中函数参数是传值传递,你在resize函数里执行array = malloc(...)时,修改的只是函数内部的局部指针变量,main函数里的arr指针完全不会受到影响。也就是说:

  • main里的arr始终指向最初分配的3个int的内存块。
  • 后续你给arr[3]到arr[29]赋值,都是在访问超出原内存块的空间,属于未定义行为,这就是你看到固定垃圾值的原因——这些内存地址不属于你的程序,内容是随机的垃圾数据。

修正后的代码

下面是修复后的版本,解决了上述所有问题:

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

// 增加old_size参数,返回新分配的数组指针
int* resize(int *array, int old_size, int newsize) {
  int *temp = malloc(sizeof(int) * 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];
  }

  int *new_array = malloc(sizeof(int) * newsize);
  if (new_array == NULL) {
    printf("Failed to allocate new list memory. Fatal error - crash.\n");
    free(temp); // 避免内存泄漏
    exit(EXIT_FAILURE);
  }

  // 复制原数据到新数组
  for (int i = 0; i < old_size; i++) {
    new_array[i] = temp[i];
  }

  // 只初始化新扩展的元素为0,不覆盖原数据
  for (int i = old_size; i < newsize; i++) {
    new_array[i] = 0;
  }

  free(temp);
  free(array); // 释放原数组内存,避免泄漏
  return new_array;
}

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;
  // 接收新指针,并传递原数组的元素个数
  arr = resize(arr, 3, 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;
}

关键修复点说明

  • 给resize函数增加old_size参数,明确告知函数原数组的元素个数,避免错误计算。
  • resize函数返回新分配的数组指针,main函数接收这个指针,替换原来的arr,确保后续操作的是新的内存块。
  • 在初始化新元素时,从old_size开始循环,避免覆盖已经复制过来的原数据(原代码会把整个新数组设为0,会丢失原数据)。
  • 释放原数组的内存,避免内存泄漏。

内容的提问来源于stack exchange,提问作者seedse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 15:23:24