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

C语言多维数组初始化与输出异常问题求助

C语言多维数组越界与字符串溢出问题修复

问题描述

我明明将数组初始化为[length*2][length/2+1][3],但实际运行起来像是[length*2][4][????]。这显然是C语言新手错误,但我找不到原因。当largo=6时,程序应输出每个arr[][]位置存储的数据,但仅显示7个中的4个,且旧数据未被清除,而是被拼接成类似"1/22/1"的形式。补充信息:若将valoresPosiblesFinal[largo*2-1][(largo/2)+1][3]的最后一个维度设为4(我以为是终止符问题),程序直接在此处停止。

原始代码

#include <stdio.h>

void dosDados(){
    int largo; //max length of the dice. it's used to calculate the length of the arrays
    int min = 2; //minor value posible
    char auxRes[4]; //I don't even use it anymore

    printf("Ingrese el largo de los dados: ");
    scanf("%d",&largo);

    char valoresPosiblesFinal[largo*2-1][(largo/2)+1][3];//array where the sets n/n are stored
    int auxArr[largo+2]; //array to know how many elements are there in each set (ie: if I saved 1/2 I don't want to overflow it with 2/1)

    for(int i = 0; i < largo-1; i++){
        auxArr[i] = 0;
    } //inialice the array auxArr to avoid erratic behavior

    for(int i = 1; i <= largo; i++){  //loop to emulate the firt dice
        for(int j = 1; j <= largo; j++){  //loop to emulate the second dice
            if((i+j >= min) && (i+j<=largo+largo)){ //Used to know if i+j is within the posible values 
                sprintf(valoresPosiblesFinal[i+j][auxArr[i+j]],"%d/%d",i,j);  //I declare that the value of valoresPosiblesFinal is "%d/%d"
                
                auxArr[i+j]++; 
            }
        }
    }

    for(int i = 0; i < largo*2-1; i++){
        for(int j = 0; j< largo/2+1;j++){
            printf("[ %s ]",valoresPosiblesFinal[i][j]);
        }
        printf("\n");
    }
}

int main(){
    dosDados();
}

问题根源与修复步骤

1. 字符串溢出导致内存污染

"%d/%d"格式的字符串(比如"6/6")需要4个字节存储:数字+斜杠+数字+\0字符串终止符。你定义的第三维度是3,刚好缺少1个字节,导致sprintf写入时越界,覆盖相邻内存区域,出现"1/22/1"这种拼接错误。
修复:把数组第三维度改为4:

char valoresPosiblesFinal[largo*2+1][(largo/2)+1][4];

2. 数组索引越界与未初始化

  • auxArr初始化不完整:你只初始化了auxArr[0]到auxArr[largo-2],但i+j的范围是2到2*largo,对应auxArr[2]到auxArr[2*largo],这些位置的初始值是随机垃圾值,导致sprintf写入到错误位置,甚至破坏栈内存。
    修复:初始化auxArr的所有用到的索引:
    int auxArr[largo*2 + 1]; // 扩大数组容量到能容纳最大索引2*largo
    for(int i = 0; i <= largo*2; i++){
        auxArr[i] = 0;
    }
    
  • 第一维度容量不足:valoresPosiblesFinal的第一维度是largo*2-1,但i+j的最大值是2*largo,索引超出数组范围(数组最大索引为largo*2-2),导致越界写内存。
    修复:把第一维度改为largo*2+1,确保能容纳所有i+j的结果:
    char valoresPosiblesFinal[largo*2+1][(largo/2)+1][4];
    

3. 输出循环范围错误

输出循环从i=0开始,而i+j的最小值是2,前两个位置的内容是未初始化的垃圾值;同时遍历整个largo/2+1个位置,会输出未使用的空元素。
修复:从i=2开始输出,只遍历每个i下的有效元素(数量为auxArr[i]):

for(int i = 2; i <= largo*2; i++){
    for(int j = 0; j < auxArr[i]; j++){
        printf("[ %s ]", valoresPosiblesFinal[i][j]);
    }
    printf("\n");
}

修复后的完整代码

#include <stdio.h>

void dosDados(){
    int largo;
    int min = 2;

    printf("Ingrese el largo de los dados: ");
    scanf("%d",&largo);

    // 修正数组维度,确保容纳字符串终止符和所有索引
    char valoresPosiblesFinal[largo*2+1][(largo/2)+1][4];
    int auxArr[largo*2 + 1];

    // 初始化所有用到的auxArr元素
    for(int i = 0; i <= largo*2; i++){
        auxArr[i] = 0;
    }

    for(int i = 1; i <= largo; i++){
        for(int j = 1; j <= largo; j++){
            int sum = i + j;
            if(sum >= min && sum <= largo*2){
                sprintf(valoresPosiblesFinal[sum][auxArr[sum]],"%d/%d",i,j);
                auxArr[sum]++;
            }
        }
    }

    // 只输出有效元素
    for(int i = 2; i <= largo*2; i++){
        printf("Suma %d: ", i);
        for(int j = 0; j < auxArr[i]; j++){
            printf("[ %s ]", valoresPosiblesFinal[i][j]);
        }
        printf("\n");
    }
}

int main(){
    dosDados();
}

内容的提问来源于stack exchange,提问作者Julian.gxnzalez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 12:18:55