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

使用fscanf从.txt文件读取数据到C动态数组时触发Access Violation错误

修复读取天体位置时的Access Violation错误

问题分析与修复步骤

1. 打印循环的数组越界

你在初始化数组后添加的打印循环中,列循环条件错误:每个天体的位置只有3个分量(x/y/z),但你使用column < numberOfBodies作为循环条件,当numberOfBodies大于3时,会访问超出每行分配的内存范围,触发未定义行为。

修复:将列循环条件改为column < 3:

for (row = 0; row < numberOfBodies; row++)
{
    for (column = 0; column < 3; column++) // 改为3,对应x/y/z三个分量
    {
        printf(" %lf", initialPositions[row][column]);
    }
    printf("\n");
}

2. 读取文件时的索引初始化错误

打开文件前,前面的循环已经把row和column的值修改到了numberOfBodies(比如numberOfBodies=5时,row=5,column=5)。此时用这个row值访问initialPositions[row],已经超出了数组的行范围(数组行索引是0到numberOfBodies-1),直接导致Access Violation。

修复:在读取文件前重新初始化row为0,同时直接用固定索引0/1/2访问列,避免依赖column变量:

// 打开文件后,重置row为0
row = 0;
while (fscanf(file, "%lf %lf %lf", &initialPositions[row][0], &initialPositions[row][1], &initialPositions[row][2]) != EOF)
{
    printf("%lf %lf %lf\n", initialPositions[row][0], initialPositions[row][1], initialPositions[row][2]);
    row++;
    // 防止读取超过numberOfBodies行,避免越界
    if (row >= numberOfBodies) break;
}

3. 跳过文件的表头行

文件第一行是文本表头pos_x, pos_y, pos_z,fscanf无法将其解析为double,会导致读取失败,后续循环逻辑混乱。

修复:用fgets跳过第一行:

FILE *file = fopen("initial_positions.txt", "r");
if (file == NULL)
{
    printf("\nUnable to access the 'initial_positions.txt' file.\n");
    exit(1);
}
else
{
    char buffer[256];
    // 跳过第一行表头
    fgets(buffer, sizeof(buffer), file);
    row = 0; // 重置row为0
    // ... 读取逻辑
}

4. 不要返回已释放的内存

你在函数末尾调用了free(initialPositions),然后返回这个指针,此时返回的是已经被释放的悬空指针,调用者使用它会触发未定义行为。

修复:移除free(initialPositions),把内存释放的责任交给调用者:

// free(initialPositions); // 删除这行
return initialPositions;

同时在main函数中调用完后记得释放内存:

int main()
{
    int numberOfBodies = 5;
    double **positions = ReadInitialPositions(numberOfBodies);
    // 使用positions的逻辑...
    // 释放内存
    for (int i = 0; i < numberOfBodies; i++)
    {
        free(positions[i]);
    }
    free(positions);
    return 0;
}

5. 内存分配的错误检查

malloc可能返回NULL(内存不足时),不检查会直接崩溃。

修复:添加malloc返回值检查,同时在分配失败时释放已分配的内存,避免泄漏:

double **initialPositions = malloc(sizeof(double*) * numberOfBodies);
if (initialPositions == NULL)
{
    printf("Failed to allocate memory for rows.\n");
    exit(1);
}
for (row = 0; row < numberOfBodies; row++)
{
    initialPositions[row] = malloc(sizeof(double) * 3);
    if (initialPositions[row] == NULL)
    {
        printf("Failed to allocate memory for row %d.\n", row);
        // 释放已分配的内存
        for (int i = 0; i < row; i++)
        {
            free(initialPositions[i]);
        }
        free(initialPositions);
        exit(1);
    }
}

修复后的完整代码

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

double **ReadInitialPositions(int numberOfBodies)
{
    int row = 0;
    int column = 0;
    double **initialPositions = malloc(sizeof(double*) * numberOfBodies);
    if (initialPositions == NULL)
    {
        printf("Failed to allocate memory for rows.\n");
        exit(1);
    }

    for (row = 0; row < numberOfBodies; row++)
    {
        initialPositions[row] = malloc(sizeof(double) * 3);
        if (initialPositions[row] == NULL)
        {
            printf("Failed to allocate memory for row %d.\n", row);
            for (int i = 0; i < row; i++)
            {
                free(initialPositions[i]);
            }
            free(initialPositions);
            exit(1);
        }
    }

    // 初始化后打印(可选,用于验证)
    for (row = 0; row < numberOfBodies; row++)
    {
        for (column = 0; column < 3; column++)
        {
            printf(" %lf", initialPositions[row][column]);
        }
        printf("\n");
    }

    FILE *file = fopen("initial_positions.txt", "r");
    if (file == NULL)
    {
        printf("\nUnable to access the 'initial_positions.txt' file.\n");
        // 释放已分配内存
        for (int i = 0; i < numberOfBodies; i++)
        {
            free(initialPositions[i]);
        }
        free(initialPositions);
        exit(1);
    }
    else
    {
        char buffer[256];
        // 跳过表头行
        fgets(buffer, sizeof(buffer), file);
        
        row = 0;
        while (fscanf(file, "%lf %lf %lf", &initialPositions[row][0], &initialPositions[row][1], &initialPositions[row][2]) != EOF)
        {
            printf("%lf %lf %lf\n", initialPositions[row][0], initialPositions[row][1], initialPositions[row][2]);
            row++;
            if (row >= numberOfBodies)
            {
                break;
            }
        }
    }

    fclose(file);
    return initialPositions;
}

int main()
{
    int numberOfBodies = 5;
    double **positions = ReadInitialPositions(numberOfBodies);
    
    // 这里可以添加使用positions的逻辑
    
    // 释放内存
    for (int i = 0; i < numberOfBodies; i++)
    {
        free(positions[i]);
    }
    free(positions);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 16:55:18