哪里是我段错误? [英] Where is my segmentation fault?

查看:110
本文介绍了哪里是我段错误?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经得到了code可以编译不够好,但是当我尝试运行它,我得到一个分段错误,我无法弄清楚什么是错的。

该计划的重点是不同的尺寸和碎片的数量fragmentet ASCII艺术文件中的文本拼凑。
该片段被命名为part_xx-YY,其中xx是从00到11和YY是从00到05。

 #包括LT&;&stdio.h中GT;
#包括LT&;&stdlib.h中GT;
#包括LT&;&string.h中GT;
INT主要(无效)
{
    INT宽度;
    INT高度;
    INT xPieces;
    INT yPieces;
    INT xTens = 0;
    INT xOnes = 0;
    INT yTens = 0;
    INT yOnes = 0;
    的printf(片段宽:);
    scanf函数(%d个,&安培;宽度);
    的printf(片段的高度:);
    scanf函数(%d个,&安培;高度);
    输出(X轴的分片数:);
    scanf函数(%d个,&安培; xPieces);
    的printf(关于y轴上的分片数:);
    scanf函数(%d个,&安培; yPieces);
    的printf(wtf0);
    字符*线=的malloc(sizeof的(宽)* sizeof的(炭));
    的printf(wtf1);
    字符数组[xPieces] [yPieces] [高度] [宽度]
    的printf(wtf2);
    字符文件名[50];
    的printf(wtf3);
    为(中间体X = 0; X&下; xPieces)
    {
        的printf(%D,X);
        对于(INT Y = 0; Y< yPieces;)
        {
            的printf(%D,Y);
            如果(xOnes> = 10)
            {
                xOnes = 0;
                xTens ++;
            }
            如果(yOnes> = 10)
            {
                yOnes = 0;
                yTens ++;
            }
            的snprintf(文件名,文件名的sizeofPART_%I%I-%I%I,xTens,xOnes,yTens,yOnes);
            FILE *文件=的fopen(文件名,R);
            炭缓冲液[(宽)*(高度)];
            的fread(缓冲液,1,(宽度)*(高度),文件);
            的for(int i = 0; I<高度;我++)
            {
                的printf(%D,我);
                对于(INT J = 0; J<宽度; J ++)
                {
                    的printf(%D,J);
                    数组[X] [Y] [i] [j]的缓冲区= [J +(我*(宽));
                }
            }
            FCLOSE(文件);
            ÿ++;
            yOnes ++;
        }
        X ++;
        xOnes ++;
    }    FILE * NEWFILE =的fopen(NEWFILE,W);    对于(INT Y = 0; Y< yPieces; Y ++)
    {
        的for(int i = 0; I<高度;我++)
        {
            为(中间体X = 0; X&下; xPieces; X ++)
            {
                对于(INT J = 0; J<宽度; J ++)
                {
                    FWRITE(安培;数组[X] [Y] [I] [J],1,1,NEWFILE);
                }
            }
        }
    }    FCLOSE(NEWFILE);
    免费(线);
}

我想出如何使用调试器,并表示有什么问题FREAD(),我认为这是我的文件名阵列造成的,但我改变了一些东西,现在我得到的调试器是这个

 计划接收信号SIGSEGV,分割过错。
0x0018d68c从/lib/tls/i686/cmov/libc.so.6 FREAD()

我想也许FREAD()试图读取到一个太小的缓冲区,所以我增加了缓冲到10000(这应该是戏剧性的矫枉过正),但很可惜,都无济于事。
我现在已经研究了不少,这个问题了几个小时的苦苦挣扎,但仍然不知道如何进一步何去何从正如我发现类似的问题并没有多大意义,我还是不够相似

我觉得在这一点上我需要别人来看看我的code,所以任何帮助将大大AP preciated。

更新:我已经更新了我的code有一些变化,现在我在这里得到一个分段错误,而不是:

 计划接收信号SIGSEGV,分割过错。
0x08049058在main()在innlev3.c:50
50 *阵列[X] [Y] [i] [j]的缓冲区= [J +(I *(*宽));

我认为这部分是pretty好......我做了什么错,在这里?

更新2: code再次更新。我发现了一些我觉得很奇怪......这些都没有的printf的我scanf的工作后... A和我回到了美好的旧FREAD()分段错误。我想这是一个很好的事情,我没有做一个新的问题出这...:P

 计划接收信号SIGSEGV,分割过错。
0x0018d68c从/lib/tls/i686/cmov/libc.so.6 FREAD()
(GDB)回溯
从/lib/tls/i686/cmov/libc.so.6#0 0x0018d68c在FREAD()
#1主0x08048fc6()


解决方案

我猜文件 NULL 大概这说明 *文件名不存在。

请注意,声明如下:

 文件名[5] =%i的,xTens;

不这样做,你可能期望。该声明等同于:

 文件名[5] = xTens;

和应该给你一个编译器警告,因为你分配一个 INT 的char *

相反,你可能想用的snprintf 使用的printf 样式的格式来构造文件名。

 字符文件名[50];
的snprintf(文件名,文件名的sizeofPART_%I%I-%I%,xTens,xOnes,yTens,yOnes);
FILE *文件=的fopen(文件名,R);


有关你的第二次碰撞:你有你并不需要在阵列指针额外的一层。声明为字符数组... 和删除 * 当你访问它。目前的情况是,你告诉编译器,该元素将是三分球,但你有没有把它们点任意位置,然后你问的编译器去看看他们正在使用指向 * 。轰!

您最终使用阵列然后需要做一个指向每个字符传递给 FWRITE 。你会做,与&安培; 运营商,被称为地址的,用来像&放大器;阵...

运算符的地址是 * 相反。一旦你的程序工作,你可以使用&安培; 等地简化你的code。例如,而不是宣布为int *宽,并使用的malloc 分配它关闭堆,你可以删除 * 无处不在,并通过&放大器;宽度 scanf函数


由于我们回到了 FREAD 段错误:检查的返回值的fopen 然后再使用它。如果是 NULL ,打印错误消息。

 如果(文件== NULL)
{
    的printf(无法打开%s \\ n,文件名);
    出口(1);
}

这可能会告诉你什么是错的。然而,这并不调试code。通常,您应该检查从调用的函数错误返回。

I've got code that compiles well enough, but when I try to run it, I get a segmentation fault and I can't figure out what's wrong.

The point of the program is to piece together the text of fragmentet ascii art files of varying dimensions and number of fragments. The fragments are named part_xx-yy where xx is from 00 to 11 and yy is from 00 to 05.

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


int main(void)
{
    int width;
    int height;
    int xPieces;
    int yPieces;
    int xTens=0;
    int xOnes=0;
    int yTens=0;
    int yOnes=0;
    printf("Fragment width: ");
    scanf("%d", &width);
    printf("Fragment height: ");
    scanf("%d", &height);
    printf("Number of fragments on x axis: ");
    scanf("%d", &xPieces);
    printf("Number of fragments on y axis: ");
    scanf("%d", &yPieces);
    printf("wtf0");
    char *line=malloc(sizeof(width) * sizeof(char));
    printf("wtf1");
    char array[xPieces][yPieces][height][width];
    printf("wtf2");
    char fileName[50];
    printf("wtf3");
    for(int x = 0; x<xPieces;)
    {
        printf("%d", x);
        for(int y = 0; y<yPieces;)
        {
            printf("%d", y);
            if(xOnes>=10) 
            {
                xOnes=0;
                xTens++;
            }
            if(yOnes>=10)
            {
                yOnes=0;
                yTens++;
            }
            snprintf(fileName, sizeof fileName, "part_%i%i-%i%i", xTens, xOnes, yTens, yOnes);
            FILE *file=fopen(fileName, "r");
            char buffer[(width) * (height)];
            fread(buffer, 1, (width) * (height), file);
            for(int i = 0; i<height; i++)
            {
                printf("%d", i);
                for(int j = 0; j<width; j++)
                {
                    printf("%d", j);
                    array[x][y][i][j] = buffer[j + (i * (width))];
                }
            }
            fclose(file);
            y++;
            yOnes++;
        }
        x++;
        xOnes++;
    }

    FILE *newFile=fopen("newFile", "w");

    for(int y = 0; y<yPieces; y++)
    {
        for(int i = 0; i<height; i++)
        {
            for(int x = 0; x<xPieces; x++)
            {
                for(int j = 0; j<width; j++)
                {
                    fwrite(&array[x][y][i][j], 1, 1, newFile);
                }
            }
        }
    }

    fclose(newFile);
    free(line);
}

I figured out how to use the debugger, and that indicated there was something wrong with fread(), which I think was caused by my fileName array, but I changed a few things and now all I get from the debugger is this:

Program received signal SIGSEGV, Segmentation fault.
0x0018d68c in fread () from /lib/tls/i686/cmov/libc.so.6

I thought perhaps fread() tried to read into a too small buffer, so I increased the buffer to 10000 (which SHOULD be dramatic overkill), but alas, to no avail. I have researched quite a bit now, struggling with this problem for a couple of hours, but still have no idea how to go further from here as what I find of similar problems doesn't make much sense to me or isn't similar enough.

I think at this point I need someone else to look at my code, so any help will be greatly appreciated.

.

.

Update: I've updated my code with a few changes, and now I get a segmentation fault here instead:

Program received signal SIGSEGV, Segmentation fault.
0x08049058 in main () at innlev3.c:50
50                      *array[x][y][i][j] = buffer[j + (i * (*width))];

I thought this part was pretty good... What have I done wrong, here?

Update 2: Code updated again. I've found something I think is very strange... Neither of those printf's after my scanf's work... Aand I'm back to the good old fread() segmentation fault. I guess it's a good thing I didn't make a new question out of this... :P

Program received signal SIGSEGV, Segmentation fault.
0x0018d68c in fread () from /lib/tls/i686/cmov/libc.so.6
(gdb) backtrace
#0  0x0018d68c in fread () from /lib/tls/i686/cmov/libc.so.6
#1  0x08048fc6 in main ()

解决方案

I'm guessing file is NULL, probably indicating that *fileName doesn't exist.

Note that statements like this:

fileName[5] = "%i",xTens;

don't do what you probably expected. That statement is equivalent to:

fileName[5] = xTens;

And that should have given you a compiler warning, since you're assigning an int to a char*.

Instead, you probably meant to use snprintf to use printf-style formatting to construct the filename.

char filename[50];
snprintf(filename, sizeof filename, "part_%i%i-%i%", xTens, xOnes, yTens, yOnes);
FILE *file=fopen(fileName, "r");


For your second crash: You have an extra layer of pointers that you don't need on array. Declare it as char array... and remove the * when you access it. As it stands now, you've told the compiler that the elements will be pointers, but you haven't made them point anywhere, and then you asked the compiler to go look where they're pointing using *. Boom!

Your final use of array then needs to make a pointer to each character to pass to fwrite. You'd do that with the & operator, called "address-of", used like &array....

The address-of operator is the opposite of *. Once you have the program working, you can use & other places to simplify your code. For example, instead of declaring int *width and allocating it off the heap using malloc, you can remove the * everywhere and pass &width to scanf.


Since we're back to the fread segfault: Check the return value of fopen before you use it. If it's NULL, print an error message.

if(file == NULL)
{
    printf("can't open %s\n", fileName);
    exit(1);
}

That will probably tell you what's wrong. However, this isn't debugging code. You should generally check for error returns from the functions you call.

这篇关于哪里是我段错误?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆