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

C语言结构体内部数组元素赋值失败问题排查求助

矩阵初始化后打印全0的问题排查与解决

问题概述

需要创建MAT_COUNT个matList结构体,每个结构体的matrix数组需正确初始化,预期打印结果为:

1.100000 2.100000
3.200000 4.200000

但实际输出全为0:

0.000000        0.000000
0.000000        0.000000

通过GDB调试时,在赋值语句执行过程中打印m[i][j]显示为0,怀疑赋值操作失败。

原代码

#include<stdio.h>
#include<stdlib.h>
#define MAT_SIZE    2
#define MAT_COUNT   3

typedef double mat[MAT_SIZE][MAT_SIZE];
typedef struct matList{
    const char *name;
    mat matrix;
}matList;

void init_mat(mat m)
{
    for(int i = 0; i < MAT_SIZE; i++){
        for(int j = 0; j < MAT_SIZE; j++){
            m[i][j] = i * 2.1 + (double) j + 1.1;
            printf("(i,j)=%f\n",m[i][j]);
        }
    }
}

//allocate matList.
matList *create_mat(const char *name)
{
    matList *tempMat = malloc(sizeof *tempMat);
    
    if(tempMat != NULL)
    {
        tempMat->name = name;
        init_mat(tempMat->matrix);
    }
    return tempMat;
}

// freematList
void free_matList(matList **mats)
{
    if(mats){
        for(int i = 0; i < MAT_COUNT; i++){
            free(mats[i]);
        }
    }
}

// return non zero if successful
int allocate_matList(matList **mats)
{
    if(mats){
        mats[0] = create_mat("MAT_A");
        mats[1] = create_mat("MAT_B");
        mats[2] = create_mat("MAT_C");
        if(mats[0] && mats[1] && mats[2])
            return 1;
    }
}

int main(void)
{
    matList *mats[MAT_COUNT];
    if(allocate_matList(mats)){
        printf("mat[2] name: %s\n",mats[2]->name);
        size_t row = sizeof(mats[2]->matrix) / sizeof (mats[2]->matrix[0]);
        size_t col = sizeof(mats[2]->matrix[0]) / sizeof(mats[2]->matrix[0][0]);
        
        printf("row: %ld col: %ld\n",row,col);    

        for(size_t i = 0; i < row; i++){
            for(size_t j = 0; j < col; j++){
                printf("%f\t",mats[2]->matrix[row][col]);
            }
            printf("\n");
        }
    }
    free_matList(mats);
    exit(EXIT_SUCCESS);
}

GDB调试信息

(gdb) break 23
Breakpoint 1 at 0x11d9: file array_struct170.c, line 23.
(gdb) s
The program is not being run.
(gdb) run
Starting program: /home/jian/helloc/a.out
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

Breakpoint 1, init_mat (m=0x5555555592a8) at array_struct170.c:23
23          for(int i = 0; i < MAT_SIZE; i++){
(gdb) s
24              for(int j = 0; j < MAT_SIZE; j++){
(gdb) s
25                  m[i][j] = i * 2.1 + (double) j + 1.1;
(gdb) print m[i][j]
$1 = 0

问题根源与解决方法

1. 打印循环的索引越界错误

main函数的打印循环中,错误地使用row和col作为数组索引:

printf("%f\t",mats[2]->matrix[row][col]);

由于MAT_SIZE=2,row和col的值均为2,而矩阵的有效索引范围是0~1,这会访问到矩阵数组的越界内存,该区域未被初始化,因此输出全0。

修正:使用循环变量i和j作为索引:

printf("%f\t",mats[2]->matrix[i][j]);

2. GDB调试的时机问题

在GDB中执行到赋值语句m[i][j] = ...时立即打印m[i][j],此时赋值操作尚未完成(代码行25还未执行结束),所以显示的是赋值前的初始值0。继续执行一步(输入s命令)后再打印,就能看到正确的赋值结果。

3. allocate_matList函数的返回值缺失

当mats为空或者任意一个create_mat调用失败时,函数没有明确返回值,会触发未定义行为。

修正:在函数末尾补充返回值:

return 0;

修正后的代码

#include<stdio.h>
#include<stdlib.h>
#define MAT_SIZE    2
#define MAT_COUNT   3

typedef double mat[MAT_SIZE][MAT_SIZE];
typedef struct matList{
    const char *name;
    mat matrix;
}matList;

void init_mat(mat m)
{
    for(int i = 0; i < MAT_SIZE; i++){
        for(int j = 0; j < MAT_SIZE; j++){
            m[i][j] = i * 2.1 + (double) j + 1.1;
            printf("(i,j)=%f\n",m[i][j]);
        }
    }
}

//allocate matList.
matList *create_mat(const char *name)
{
    matList *tempMat = malloc(sizeof *tempMat);
    
    if(tempMat != NULL)
    {
        tempMat->name = name;
        init_mat(tempMat->matrix);
    }
    return tempMat;
}

// freematList
void free_matList(matList **mats)
{
    if(mats){
        for(int i = 0; i < MAT_COUNT; i++){
            free(mats[i]);
        }
    }
}

// return non zero if successful
int allocate_matList(matList **mats)
{
    if(mats){
        mats[0] = create_mat("MAT_A");
        mats[1] = create_mat("MAT_B");
        mats[2] = create_mat("MAT_C");
        if(mats[0] && mats[1] && mats[2])
            return 1;
    }
    return 0; // 补充缺失的返回值
}

int main(void)
{
    matList *mats[MAT_COUNT];
    if(allocate_matList(mats)){
        printf("mat[2] name: %s\n",mats[2]->name);
        size_t row = sizeof(mats[2]->matrix) / sizeof (mats[2]->matrix[0]);
        size_t col = sizeof(mats[2]->matrix[0]) / sizeof(mats[2]->matrix[0][0]);
        
        printf("row: %ld col: %ld\n",row,col);    

        for(size_t i = 0; i < row; i++){
            for(size_t j = 0; j < col; j++){
                printf("%f\t",mats[2]->matrix[i][j]); // 使用i,j作为索引
            }
            printf("\n");
        }
    }
    free_matList(mats);
    exit(EXIT_SUCCESS);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 12:25:42