简体   繁体   English

为什么运行程序时出现“ Segmentation Fault”错误?

[英]Why am I getting “Segmentation Fault” when I run my program?

My program decodes an image that is covered by random pixels, to decode the image, I have to multiply each pixel's red color component by 10. The green and blue color components are the same values as the new red component. 我的程序对由随机像素覆盖的图像进行解码,要对图像进行解码,我必须将每个像素的红色分量乘以10。绿色和蓝色分量与新的红色分量的值相同。 I've created multiple helper functions, to make the code easier to read in main, but when I try to run my a.out, I keep getting "Segmentation Fault". 我创建了多个辅助函数,以使代码在main中更易于阅读,但是当我尝试运行a.out时,会不断收到“ Segmentation Fault”。 I can't seem to find my mistakes! 我似乎找不到我的错误! Help is appreciated. 感谢帮助。

void check_argument(int arg_list)
{
   if (arg_list < 2)
   {
      perror("usage: a.out <input file>\n");
   }
}

void print_pixel(int a, FILE *out)
{
   int r, g, b;

   r = a * 10;

   if (r > 255)
   {
      r = 255;
   }

   g = r;
   b = r;

   fprintf(out, "%d\n", r);
   fprintf(out, "%d\n", g);
   fprintf(out, "%d\n", b);
}

void read_header(FILE *in)
{
   char str[20];

   for (int i = 0; i < 3; i++)
   {
      fgets(str, 20, in);
   }
}

FILE*  open_files(FILE *infile, char *input[])
{
   infile = fopen(input[1], "r");

   if (infile == NULL)
   {
      perror("Error: Cannot read file.\n");
   }

   return infile;
}

void decode(int arg_list, char *in[])
{
   FILE *input, *output;

   int check, red, green, blue;

   open_files(input, in);
   output = fopen("hidden.ppm", "w");

   fprintf(output, "P3\n");
   fprintf(output, "%d %d\n", 500, 375);
   fprintf(output, "255\n");

   read_header(input);
   check = fscanf(input, "%d %d %d", &red, &green, &blue);

   while (check != EOF)
   {
      print_pixel(red, output);
      check = fscanf(input, "%d %d %d", &red, &green, &blue);
   }

   fclose(input);
   fclose(output);
}

int main(int argc, char *argv[])
{
   check_argument(argc);
   decode(argc, argv);
}

As this is supposed to be homework, I'll try to show you the some common source of bugs and how to find them. 由于这应该是家庭作业,因此我将尝试向您展示一些常见的bug来源以及如何查找它们。

  1. Variables which are used must (should) be assigned to before that. 在此之前,必须(应该)将使用的变量分配给它。 This counts especially for pointers, eg FILE * . 这对于指针尤其重要,例如FILE *

  2. If a function (eg fopen() ) fails, it normally indicates this by returning a special value which must be checked before continuing. 如果一个函数(例如fopen() )失败,它通常通过返回一个特殊值来表示这一点,在继续之前必须检查该值。

  3. To check which value a variable has, you can use printf() to show it. 要检查变量具有哪个值,可以使用printf()来显示它。

This is for finding principal errors such as segfaults. 这是为了查找主要错误,例如段错误。

But logical errors are hard to find as well: if you read 3 values and store them into variables, it might be more useful to use them all instead of only one of them. 但是,逻辑错误也很难找到:如果读取3个值并将它们存储到变量中,则全部使用它们而不是仅使用其中一个可能会更有用。 (But maybe this one is not yet the goal of this exercise.) (但也许这不是此练习的目标。)


I wrote the lines before this before I learned that it is not the task to search for bugs in a given program, but to write a program by yourself, so I'll get a little more concrete by now. 在了解到这不是在给定程序中搜索错误的任务,而是自己编写程序之前,我先写了几行,所以现在我将更加具体。

A FILE * is something returned by fopen() . FILE *fopen()返回的东西。 You can return it or you can write it to a variable or another memory location indirectly pointed to by a pointer "one level deeper". 您可以返回它,也可以将其写入变量或指针“更深一层”间接指向的另一个存储位置。

So you should rewrite your open_files() (BTW: why file* s *? It's currently only one...): 因此,您应该重写open_files() (顺便说一句:为什么file * s *?它目前只有一个...):

either for returning the value (preferrable): 用于返回值(首选):

FILE* open_files(char *input[])
{
   FILE *infile = fopen(input[1], "r");

   if (infile == NULL)
   {
      perror("Error: Cannot read file.\n");
   }

   return infile;
}

and call it with 并用

input = open_files(input);

or with "pass by reference": 或“通过引用传递”:

void open_files(FILE **infile, char *input[])
{
   *infile = fopen(input[1], "r");

   if (*infile == NULL)
   {
      perror("Error: Cannot read file.\n");
   }

   return *infile;
}

and call it with 并用

open_files(&input, in);

Only doing that you'll have your variable input at the caller's site really written to. 只有这样做,您才能真正在调用者的站点上input变量input

After calling open_files(input, in); 调用open_files(input, in); you will not have the file handle in input . 您将在input没有文件句柄。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM