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

自定义cell类型二维数组resizeArray函数异常排查求助

问题排查与修复:自定义二维数组resize函数异常

问题描述

尝试编写resizeArray函数用于调整自定义cell类型二维数组的大小,内存分配失败时返回错误信息,但代码无法正常运行,编译器无警告,怀疑返回指针类型不匹配。

原始代码

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

typedef struct
{
  int variable_1;
  int variable_2;
  char character;
} cell;

unsigned long max(unsigned long a, unsigned long b)
{
  if (a >= b)
    return a;
  else
    return b;
}

void initialiseArray(unsigned long rows, unsigned long columns,
                     cell array[rows][columns])
{
  for (unsigned long i = 0; i < rows; i = i + 1)
    for (unsigned long j = 0; j < columns; j = j + 1)
    {
      array[i][j].variable_1 = 0;
      array[i][j].variable_2 = 0;
      array[i][j].character = ' ';
    }
}

cell *resizeArray(unsigned long rows, unsigned long columns,
                  unsigned long *array_rows, unsigned long *array_columns,
                  cell array[*array_rows][*array_columns])
{
  if (rows > *array_rows || columns > *array_columns)
  {
    unsigned long new_array_rows = max(rows, *array_rows);
    unsigned long new_array_columns = max(columns, *array_columns);
    cell (*new_array)[new_array_rows][new_array_columns] = malloc(sizeof *new_array);
    if (new_array == NULL)
    {
      printf("Error in \"resize\": Memory could not be allocated.\n");
      return NULL;
    }
    else
      free(array);
    *array_rows = new_array_rows;
    *array_columns = new_array_columns;
    return new_array;
  }
}

int main(void)
{
  unsigned long array_rows = 10;
  unsigned long array_columns = 15;
  cell (*array)[array_rows][array_columns] = malloc(sizeof *array);
  if (array == NULL)
  {
    printf("Error in \"main\": Memory could not be allocated.\n");
    return 3;
  }
  cell *new_array = resizeArray(15, 15, &array_rows, &array_columns, *array);
  if (new_array == NULL)
    printf("Memory error. We stop the program.\n");
  return -1;
  array = new_array;
  initialiseArray(array_rows, array_columns, *array);
  return 0;
}

核心问题分析

  1. 指针类型严重不匹配

    • resizeArray函数声明返回cell*,但实际返回的是cell (*)[new_array_rows][new_array_columns](指向二维变长数组的指针),两种类型完全不兼容。编译器未警告是因为隐式指针转换,但这会导致未定义行为,是代码崩溃的核心原因。
  2. main函数逻辑错误

    • return -1;语句直接写在错误判断之后,导致后续的array = new_array;和初始化代码永远不会执行,程序直接退出。
  3. 内存释放错误

    • 函数参数中的cell array[*array_rows][*array_columns]会被编译器退化为cell (*)[*array_columns](指向一维数组的指针),此时free(array)释放的是数组首元素的指针,而非原来在main中分配的二维数组指针,会导致内存泄漏或双重释放问题。
  4. 函数无返回值分支

    • 当不需要扩容时,resizeArray没有返回值,触发未定义行为。

修复后的代码

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

typedef struct
{
  int variable_1;
  int variable_2;
  char character;
} cell;

unsigned long max(unsigned long a, unsigned long b)
{
  return (a >= b) ? a : b;
}

void initialiseArray(unsigned long rows, unsigned long columns,
                     cell (*array)[columns])
{
  for (unsigned long i = 0; i < rows; ++i)
    for (unsigned long j = 0; j < columns; ++j)
    {
      array[i][j].variable_1 = 0;
      array[i][j].variable_2 = 0;
      array[i][j].character = ' ';
    }
}

// 返回指向一维数组的指针(模拟二维数组),统一类型
cell (*resizeArray(unsigned long rows, unsigned long columns,
                   unsigned long *array_rows, unsigned long *array_columns,
                   cell (*old_array)[*array_columns]))[]
{
  // 不需要扩容时直接返回原数组
  if (rows <= *array_rows && columns <= *array_columns)
  {
    return old_array;
  }

  unsigned long new_rows = max(rows, *array_rows);
  unsigned long new_cols = max(columns, *array_columns);

  // 分配新内存:按元素总数分配,避免变长数组指针的兼容性问题
  cell (*new_array)[new_cols] = malloc(sizeof(cell) * new_rows * new_cols);
  if (new_array == NULL)
  {
    printf("Error in \"resize\": Memory could not be allocated.\n");
    return NULL;
  }

  // 释放原数组内存
  free(old_array);

  // 更新行列数
  *array_rows = new_rows;
  *array_columns = new_cols;

  return new_array;
}

int main(void)
{
  unsigned long array_rows = 10;
  unsigned long array_columns = 15;

  // 初始分配:用指向一维数组的指针模拟二维数组,简化类型处理
  cell (*array)[array_columns] = malloc(sizeof(cell) * array_rows * array_columns);
  if (array == NULL)
  {
    printf("Error in \"main\": Memory could not be allocated.\n");
    return 3;
  }

  cell (*new_array)[array_columns] = resizeArray(15, 15, &array_rows, &array_columns, array);
  if (new_array == NULL)
  {
    printf("Memory error. We stop the program.\n");
    free(array);
    return -1;
  }

  // 更新数组指针并初始化
  array = new_array;
  initialiseArray(array_rows, array_columns, array);

  // 后续业务逻辑...

  // 最后释放内存
  free(array);
  return 0;
}

修复说明

  1. 统一指针类型

    • 将数组改为用cell (*)[cols](指向一维数组的指针)模拟二维数组,resizeArray返回同类型指针,彻底解决类型不匹配问题。
  2. 修正main函数逻辑

    • 仅在内存分配失败时执行return -1;,确保正常流程下初始化代码能执行。
  3. 修复内存管理

    • 直接传入原数组的指针进行释放,避免退化后的指针错误释放问题;补充无需扩容时的返回逻辑,消除无返回值的未定义行为。
  4. 优化内存分配方式

    • 按元素总数分配内存,避免变长数组指针的兼容性限制,提升代码可移植性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:44:58