2012-11-12 39 views
1

我已经有了编译好的代码,但是当我尝试运行它时,出现了分段错误,我无法弄清楚什么是错误的。我的分段错误在哪里?

该计划的重点是将不同尺寸和片段数量的碎片文件文件拼凑在一起。 片段被命名为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() ,我想这是我的文件名阵列造成的,但我改变了一些东西,现在我在调试器得到的是这样的:

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

你应该问你的调试器这种类型的问题。 – 2012-11-12 02:13:03

+0

我已经更新了一个新的分段错误。这是好的还是我应该提出一个新的问题? – Dzyu

+0

我想说这足以让我成为一个单独的问题,但我怀疑Stack Overflow警察会来敲门。 ;-)我在下面回答你的新问题。 –

回答

3

我猜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。您可以使用&运营商的名称,称为“address-of”,用于&array...

地址运算符与*相反。一旦你的程序工作,你可以使用&其他地方来简化你的代码。例如,您可以不使用声明int *width并使用malloc从堆中分配它,而是可以将*随处移除,并将&width更改为scanf


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

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

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

+0

啊,我明白了。这使我通过fread()segfault,但现在我又得到了另一个: 编程接收到的信号SIGSEGV,分段错误。在innlev3.c 0x08049058在main():50 50 \t \t \t \t \t \t *阵列[X] [Y] [i] [j] =缓冲液[J +(I *(*宽度))]; – Dzyu

+0

啊,我已经开始讨论这个问题了。很高兴知道我对这些指针有了更好的掌握。 :) 我现在又回到旧fread()分段错误,我发现一个好奇心:没有任何printf(“我添加的wtf,打印...代码更新和您的帮助非常感谢。:) – Dzyu

+0

你的'printf'调用正在工作,但是因为你没有在它们的末尾添加换行符“\ n”,所以它们的输出会被缓冲,直到你打印换行符 –

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; 

我想您所想的蟒蛇。

+0

这似乎不是真的 - 有一个'scanf'应该设置'* width'。 –

+0

@JameySharp:但是scanf是在* width被使用后完成的。 –

+0

啊,我明白了你的观点 - 但是随后使用未初始化的'width'分配的变量'line'不会在任何地方使用,并且不会在那里发生崩溃,而是在稍后发生。 –

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()中的文件变量似乎不正确。

+0

感谢您的回溯提示。我将在未来使用它。 :) 现在,更新我的代码后出现的新分段错误只给了我同样的事情,如果我做一个简单的回溯,并且我在这里也看不到我的代码有什么问题。 – Dzyu

1

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