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

C语言分配结构体二维数组实现棋盘遇运行时错误求解决

代码改进建议及实现思路

原代码的问题分析

  • 函数参数int** board完全冗余,函数内部重新分配内存并返回指针,这个参数无实际作用
  • malloc类型转换错误:(int*)应改为(int**)(C中可省略强制转换,但转换时需匹配类型)
  • 内存分配失败后return;不符合函数返回类型要求,应返回NULL
  • 未检查每行malloc的返回值,若某一行分配失败,已分配的内存无法释放,造成内存泄漏
  • 函数内打印输入提示但未读取size的值,若调用时传入的size是未初始化的垃圾值,会引发非法内存访问

改进后的int类型二维数组代码

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

int** makeboard(int size)
{
    // 先校验尺寸合法性
    if (size <= 0) {
        printf("Invalid board size\n");
        return NULL;
    }

    int** board = malloc(size * sizeof(int*));
    if (!board) {
        perror("Failed to allocate row pointers");
        return NULL;
    }

    for (int i = 0; i < size; i++) {
        board[i] = malloc(size * sizeof(int));
        if (!board[i]) {
            perror("Failed to allocate row data");
            // 释放已分配的内存,避免泄漏
            for (int j = 0; j < i; j++) {
                free(board[j]);
            }
            free(board);
            return NULL;
        }
        // 可选:初始化元素为0,避免垃圾值干扰
        for (int k = 0; k < size; k++) {
            board[i][k] = 0;
        }
    }

    return board;
}

// 配套的内存释放函数
void freeboard(int** board, int size)
{
    if (!board) return;
    for (int i = 0; i < size; i++) {
        free(board[i]);
    }
    free(board);
}

不同的实现思路

1. 单块内存分配二维数组

将二维数组作为连续内存块分配,减少内存碎片,访问效率更高:

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

// 返回一维指针,通过索引计算访问二维元素:board[row * size + col]
int* makeboard_single(int size)
{
    if (size <= 0) {
        printf("Invalid board size\n");
        return NULL;
    }

    int* board = malloc(size * size * sizeof(int));
    if (!board) {
        perror("Failed to allocate board");
        return NULL;
    }

    // 初始化所有元素为0
    for (int i = 0; i < size * size; i++) {
        board[i] = 0;
    }

    return board;
}

// 释放时直接调用free(board);即可

2. 使用结构体封装棋盘

适合后续扩展为自定义结构体类型的棋盘,便于维护和扩展属性:

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

// 定义棋盘格子的结构体,可扩展更多属性
typedef struct {
    int value;
    // 示例:添加颜色、选中状态等属性
    // int color;
    // int is_selected;
} ChessPiece;

// 封装整个棋盘的结构体
typedef struct {
    int size;
    ChessPiece** grid;
} ChessBoard;

ChessBoard* make_chessboard(int size)
{
    if (size <= 0) {
        printf("Invalid board size\n");
        return NULL;
    }

    ChessBoard* board = malloc(sizeof(ChessBoard));
    if (!board) {
        perror("Failed to allocate board struct");
        return NULL;
    }
    board->size = size;

    board->grid = malloc(size * sizeof(ChessPiece*));
    if (!board->grid) {
        perror("Failed to allocate row pointers");
        free(board);
        return NULL;
    }

    for (int i = 0; i < size; i++) {
        board->grid[i] = malloc(size * sizeof(ChessPiece));
        if (!board->grid[i]) {
            perror("Failed to allocate row data");
            // 回滚已分配内存
            for (int j = 0; j < i; j++) {
                free(board->grid[j]);
            }
            free(board->grid);
            free(board);
            return NULL;
        }
        // 初始化每个格子的属性
        for (int k = 0; k < size; k++) {
            board->grid[i][k].value = 0;
            // board->grid[i][k].color = 0;
        }
    }

    return board;
}

// 配套的释放函数
void free_chessboard(ChessBoard* board)
{
    if (!board) return;
    for (int i = 0; i < board->size; i++) {
        free(board->grid[i]);
    }
    free(board->grid);
    free(board);
}

3. 变长数组(VLA)(栈分配,适合小棋盘)

如果棋盘尺寸不大,可直接在栈上分配变长数组,无需手动管理内存,但注意栈空间有限(通常仅几MB):

#include <stdio.h>

void makeboard_vla(int size)
{
    // 限制尺寸避免栈溢出
    if (size <= 0 || size > 1000) {
        printf("Invalid board size\n");
        return;
    }

    int board[size][size];
    // 初始化所有元素为0
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            board[i][j] = 0;
        }
    }

    // 直接使用棋盘即可,函数结束后栈内存自动释放
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 10:46:15