我的分段错误在哪里?

时间:2012-11-12 01:57:30

标签: c linux gdb

我已经编写了足够好的代码,但是当我尝试运行它时,我遇到了分段错误,我无法弄清楚出了什么问题。

该计划的目的是拼凑不同维度和碎片数量的fragmentet ascii艺术文件的文本。 片段命名为part_xx-yy,其中xx为00到11,yy为00到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);
}

我想出了如何使用调试器,这表明fread()有问题,我认为这是由我的fileName数组引起的,但是我改变了一些东西,现在我从调试器得到的就是这个:

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

我想也许fread()试图读入一个太小的缓冲区,所以我将缓冲区增加到10000(这应该是戏剧性的过度杀伤),但唉,无济于事。 我现在已经研究了很多,在这个问题上挣扎了几个小时,但仍然不知道如何从这里走得更远,因为我发现类似的问题对我来说没有多大意义或者不够相似

我认为此时我需要其他人查看我的代码,所以我们将非常感谢您的帮助。

更新:我已经通过一些更改更新了我的代码,现在我在这里遇到了分段错误:

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

我认为这部分非常好......我做错了什么,这里?

更新2:代码再次更新。我发现了一些我觉得非常奇怪的东西......在我的scanf工作之后,这些printf都没有... Aand我回到了旧的fread()分段错误。我想这是一件好事,我没有提出一个新问题......: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 ()

4 个答案:

答案 0 :(得分:3)

我猜fileNULL,可能表示*fileName不存在。

请注意这样的陈述:

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

不要做你想要的。该陈述相当于:

fileName[5] = xTens;

这应该给你一个编译器警告,因为你正在为int分配一个char*

相反,您可能打算使用snprintf来使用printf样式格式来构造文件名。

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

对于你的第二次崩溃:你在array上有一个额外的指针层,你不需要它。将其声明为char array...,并在访问时删除*。就像现在一样,你已经告诉编译器元素将是指针,但是你没有把它们指向任何地方,然后你要求编译器使用*查看它们指向的位置。吊杆!

您最后使用array然后需要指向要传递给fwrite的每个字符的指针。您可以使用名为“address-of”的&运算符执行此操作,使用类似&array...

address-of运算符与*相反。使程序运行后,您可以使用&个其他位置来简化代码。例如,您可以使用int *width声明malloc并将其从堆中分配出去,而不是在任何地方删除*并将&width传递给scanf


由于我们回到fread段错误:在使用之前检查fopen的返回值。如果是NULL,则打印错误消息。

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

这可能会告诉你什么是错的。但是,这不是调试代码。您通常应该检查您调用的函数的错误返回。

答案 1 :(得分:2)

在使用之前,您没有将*宽度设置为任何内容。

您希望在阅读尺寸后进行分配。

printf("fragment width: ");
scanf("%i", width);
printf("fragment height: ");
scanf("%i", height);
char *line=malloc(sizeof(*width) * sizeof(char));

此外,这不符合你的想法:

        FILE *file=fopen(*fileName, "r");

它将打开一个名为“p”的文件。

这不符合你的想法:

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

我认为你在想python。

答案 2 :(得分:1)

如果您运行gdb并回溯,则会看到:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a8a724 in fread () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) backtrace
#0  0x00007ffff7a8a724 in fread () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x0000000000400ad1 in main ()

这意味着你在fread崩溃了。 fread()中的文件变量似乎不正确。

答案 3 :(得分:1)

+1学习使用调试器:)你没有检查“fopen”的返回值。 file传递给fread的价值是多少?