本文介绍了用C二维数组的指针访问,分段故障的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图写一个康威在C.生命游戏一个code我有包含我的宇宙一些问题二维数组。我会告诉你,导致我一个问题,code的部分。其实有两个问题,我不能处理的。

 的#include<&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括file2ppm.h的typedef枚举{假的,真正的布尔};无效* allocateMemoryFor2DArray(INT X,int y)对; //分配内存的二维数组
无效initializeUniverseFromFile(字符*路径,诠释的x,INT Y,int数组[X] [Y]); //从文件单元的设定值
无效initializeUniverseRandomly(INT X,INT Y,int数组[X] [Y]); //设置随机值
INT getNumberOfColumns(FILE *文件); //获取文件列数(宇宙yDim)
诠释getNumberOfLines(FILE *文件); //获取文件的行数(宇宙xDim)
无效print2DArray(INT X,INT Y,int数组[X] [Y]); //打印二维数组
无效setDimensionsFromFile(字符*路径,诠释* xDim,为int * yDim,为int * xDimB,为int * yDimB); //设置宇宙的尺寸INT主(INT ARGC,CHAR *的argv [])
{
    INT I,J,N; //循环指标
    INT n步; //世代数
    INT IM,IP,JM,JP; //邻居的边界
    INT yDim,xDim;由用户(生活区)//定义宇宙boundarier;
    INT xDimB,yDimB; //宇宙的边界由1扩大到每侧
    INT nsum,ISUM; //邻居的总和,迭代后活细胞的总和
    // ** INT老,**新; //宇宙
    INT(*旧)[xDimB]; //宇宙
    INT(*新)[xDimB]; //宇宙    浮X; //随机化第一人口
    字符* inputPath; //路径与ixDimBtial uxDimBverse文件
    字符* outputPath; //路径输出PPM文件
    //临时副本
    INT yDim_copy,xDim_copy;    的printf(ARGC数:%d \\ n,ARGC);
    开关(ARGC){
        案例4://从文件中读取最初的宇宙
            //带参数
            n步=的atoi(ARGV [1]); //获取迭代次数
            outputPath =的argv [2]; //获取outputimages路径
            inputPath = argv的[3]; //文件与初始化uxDimBverse;
            setDimensionsFromFile(inputPath,&安培; xDim,&安培; yDim,&安培; xDimB,&安培; yDimB);
            老= allocateMemoryFor2DArray(xDimB,yDimB); // Alocate内存扩展宇宙
            新= allocateMemoryFor2DArray(xDimB,yDimB);
            的printf(初始化之前:yDim:%D,xDim数:%d \\ n,yDim,xDim); //这里的值都不错
            // tmp目录拷贝
            yDim_copy = yDim;
            xDim_copy = xDim;
            initializeUniverseFromFile(inputPath,xDim,yDim,老);
            的printf(后初始化:yDim:%D,xDim数:%d \\ n,yDim,xDim); //这里人们朦胧改变
            yDim = yDim_copy; //我拿了一份避免这个问题,现在
            xDim = xDim_copy;            的printf(从副本服用后​​:yDim:%D,xDim数:%d \\ n,yDim,xDim); //这里的尺寸是很好的再次
            的memcpy(新,老,xDimB * yDimB * sizeof的(旧[xDimB] [yDimB])); //复制旧到新
            打破;
        默认:
            的printf(用法:%s的iter_number,output_name中,yDim,xDim \\ N的argv [0]);
            的printf(或\\ n);
            的printf(用法:%s的iter_number,output_name中,ixDimBtial_input_name \\ N的argv [0]);
            的printf(注:初始文件必须在./data/\
);
            返回1;
    }    print2DArray(xDim,yDim,老); //这工作正常
    的printf(在主:yDim:%D,xDim数:%d \\ n,yDim,xDim);
    的printf(%d个\\ N,老[0] [0]); //这工作正常
    的printf(%d个\\ N,老[2] [2]); //分割失败    返回0;
}无效* allocateMemoryFor2DArray(INT X,int y)对{
    INT(*数组)[Y] =的malloc(sizeof的(INT [X] [Y])); //分配内存
    如果(阵列== NULL){/ *经常检查的malloc *返回/
        PERROR(malloc的);
        出口(EXIT_FAILURE);
    }
    返回数组;
}INT getNumberOfColumns(FILE *文件){
    INT yDim = 0;
    焦炭CH;    做
    {
        CH = GETC(文件); //从文件1字符        如果(CH =='\\ n')//如果Ch是新生产线
        {
            倒带(文件); //移动文件指针到文件的beginxDimBng
            返回yDim; //发现数列
        }
        其他
            ++ yDim;    }而(CH = EOF!);
}INT getNumberOfLines(FILE *文件){
    INT xDim = 0;
    焦炭CH;    做
    {
        CH = GETC(文件); //从文件1字符
        如果(CH =='\\ n')//如果新行
        {
            ++ xDim; //增加xDim(另一行)
        }
    }而(CH = EOF!);
    倒带(文件); //移动文件指针到文件的beginxDimBng
    返回xDim;
}
无效print2DArray(INT X,INT Y,int数组[X] [Y])
{
    INT I,J;
    的printf(X:%D,Y数:%d \\ n,X,Y);
    对于(i = 1; I< = X ++ I)
    {
        为(J = 1; J< = Y ++ j)条
        {
            的printf(%d个,数组[I] [J]);
        }
        的printf(\\ n);
    }
}无效setDimensionsFromFile(字符*路径,诠释* xDim,为int * yDim,为int * xDimB,为int * yDimB)
{
    FILE *文件;
    INT I,J;
    文件= FOPEN(路径,R); //打开文件
    如果(文件)
    {
        * yDim = getNumberOfColumns(文件);
        * xDim = getNumberOfLines(文件);
        * xDimB = * xDim + 2; //添加2为左和右环面拓扑
        * yDimB = * yDim + 2;
        如果(* xDim大于0&放大器;&放大器; * yDim大于0)
        {
            的printf(UxDimBverse尺寸%深x%d个\\ N,* xDim,* yDim);
        }
        其他
        {
            PERROR(错误初始化文件);
            出口(EXIT_FAILURE);
        }        FCLOSE(文件); //关闭文件
    }
    其他
    {
        PERROR(打开初始化文件错误);
        出口(EXIT_FAILURE);
    }
}
无效initializeUniverseFromFile(字符*路径,诠释的x,INT Y,int数组[X] [Y])
{
    FILE *文件;
    INT I,J;
    文件= FOPEN(路径,R); //打开文件
    如果(文件)
    {
        // IxDimBtialize阵列
        字符* CH;
        对于(i = 1; I< = X,我++)
        {
            //输出(I:%D,我);
            为(J = 1; J< = Y; J ++)
            {
                //的printf(歼数:%d,J);
                如果(的fscanf(文件%C,CH)!= 1)
                {
                    PERROR(读取错误。\\ n);
                }
                否则,如果(ISDIGIT((无符号字符)* CH))
                {
                    的printf(%D,与atoi(CH));
                    数组[I] [J] =的atoi(CH);
                }
                其他
                {
                    //输出(NUMER znaku数:%d,CH);
                    j--;
                }
            }
            的printf(\\ n);
        }
        的printf(读完\\ n);
        FCLOSE(文件); //关闭文件
    }
    其他
    {//文件打开错误
        PERROR(打开初始化文件错误);
        出口(EXIT_FAILURE);
    }
    的printf(在初始化yDim:%D,xDim数:%d \\ n,X,Y);
}无效initializeUniverseRandomly(INT X,INT Y,int数组[X] [Y])
{
    INT I,J;
    浮 - [R;
    对于(i = 1; I< = X,我++){
        为(J = 1; J< = Y; J ++){
            R = RAND()/((浮点)RAND_MAX + 1);
            如果(R小于0.5){
                数组[I] [J] = I * X + J;
            }
            其他{
                数组[I] [J] = I * X + J;
            }
        }
    }
}

问题1:
我设置的宇宙(变量xDim和yDim)的尺寸。我打印出来的线45(查看评论//这里的值好)。然后,我打电话 initializeUniverseFromFile(inputPath,xDim,yDim,老);
和尺寸的一个值被改变。我不知道为什么。这就是为什么我做这个变量的临时副本,因为我花了2小时寻找那个错误。我甚至在那个 initializeUniverseFromFile 函数的最后打印出这个变量,它们是很好的。但是,当我回到主试(50行),该值被改变。这是小问题。更糟的是:

问题2
我有一个指针
    INT(*旧)[xDimB];

xDimB是xDim + 2,因此它总是比xDim

更大

我初始化函数数组
allocateMemoryFor2DArray(xDimB,yDimB)

然后我做到这一点:

  print2DArray(xDim,yDim,老); //这工作正常
的printf(在主:yDim:%D,xDim数:%d \\ n,yDim,xDim); //尺寸都很好
的printf(%d个\\ N,老[0] [0]); //这工作正常
对于(i = 0; I< = xDim ++ I)
     的printf(%d个老[0] [i]; //这工作太细
的printf(%d个\\ N,老[2] [2]); //分割失败

印刷与功能全阵列是罚款
从第一行打印值都很好
从阵列的中间值打印错误创建


解决方案

You need these to contain valid numbers before you declare the VLAs int (*old)[xDimB]; and int (*new)[xDimB];. Move these VLA declarations to a latter point in the program, when xDim and yDim have known, verified values.

这篇关于用C二维数组的指针访问,分段故障的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

06-05 08:37