我的分段错误在哪里?

我已经有了编译好的代码,但是当我尝试运行它时,出现了分段错误,我找不出什么错误。

该scheme的重点是拼凑不同规模和片段数量的碎片文件。 片段命名为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); } 

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

 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()细分故障。 我想这是一件好事,我没有提出一个新的问题

 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 () 

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

请注意,像这样的陈述:

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

不要做你可能期望的事情。 该声明相当于:

 fileName[5] = xTens; 

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

相反,你可能打算使用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 。 你可以用&运算符来实现,叫做“地址 – ”,就像&array...

操作符的地址与*相反。 一旦你的程序工作,你可以使用&其他地方来简化你的代码。 例如,不是声明int *width ,而是使用malloc从堆中分配它,可以将*处处删除,并将&width传递给scanf


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

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

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

在使用之前,您没有设置宽度。

在阅读完尺寸后,您想要进行分配。

 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。

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

如果你运行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()文件变量似乎不正确。