繁体   English   中英

在涉及结构和指针的 C 编程问题上出现分段错误

[英]Getting segmentation fault on this C programming problem involving structures and pointers

我正在研究一个 Hackerrank 问题。 我应该使用给定的代码解决问题。

这是给定的代码:

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

struct Geometry;

void initRectangle(struct Geometry **object);
void initSquare(struct Geometry **object);
void initCircle(struct Geometry **object);
void initLine(struct Geometry **object);

void printGeometry(struct Geometry* object);

void freeGeometry(struct Geometry* object);

#define SCANF_FMT_CIRCLE    "%f %f %f"
#define SCANF_FMT_RECTANGLE "%f %f %f %f"
#define SCANF_FMT_SQUARE    "%f %f %f"
#define SCANF_FMT_LINE      "%f %f %f %f"


#define PRINTF_FMT_CIRCLE    "Circle with center at %f, %f and radius %f\n"
#define PRINTF_FMT_RECTANGLE "Rectangle with corner at (%f, %f) with width %f and height %f\n"
#define PRINTF_FMT_SQUARE    "Square with corner at (%f, %f) and side %f\n"
#define PRINTF_FMT_LINE      "Line from (%f, %f) to (%f, %f)\n"

int main()
{
  int n;
  struct Geometry **object;
  scanf("%d", &n);
  printf("%d geometric items\n", n);

  object = malloc(sizeof(struct Geometry*)*n);

  for(int i = 0; i < n; i++)
  {
    char objectType[40];
    scanf("%s", objectType);

    if(!strcmp(objectType, "Rectangle"))
    {
      initRectangle(&object[i]);
    }
    else if (!strcmp(objectType, "Square"))
    {
      initSquare(&object[i]);
    }
    else if(!strcmp(objectType, "Circle"))
    {
      initCircle(&object[i]);
    }
    else if(!strcmp(objectType, "Line"))
    {
      initLine(&object[i]);
    }
    else
    {
      printf("Unknown geometric type %s\n", objectType);
      exit(1);
    }

  }
  
  for(int i = 0; i < n; i++)
  {
    printGeometry(object[i]);
  }
  
  for(int i = 0; i < n; i++)
  {
    freeGeometry(object[i]);
  }

  free(object);
}

样本输入:

6
Line 0.739 0.053 0.380 0.383
Line 0.098 0.158 0.546 0.531
Square 0.120 0.707 0.346
Rectangle 0.769 0.041 0.995 0.859
Rectangle 0.671 0.520 0.246 0.226
Square 0.333 0.721 0.249

样品 Output:

6 geometric items
Line from (0.739000, 0.053000) to (0.380000, 0.383000)
Line from (0.098000, 0.158000) to (0.546000, 0.531000)
Square with corner at (0.120000, 0.707000) and side 0.346000
Rectangle with corner at (0.769000, 0.041000) with width 0.995000 and height 0.859000
Rectangle with corner at (0.671000, 0.520000) with width 0.246000 and height 0.226000
Square with corner at (0.333000, 0.721000) and side 0.249000

我需要编写函数。

我尝试了什么:

我写了一个结构,带有一些布尔变量来指示正在考虑的几何项目:

struct Geometry
{
    bool isrectangle, isquare, isline, iscircle;
    float x1, x2, y1, y2;
    float square_corner1, square_corner2, side;
    float center1, center2, radius;
    float rectangle_corner1, rectangle_corner2, width, height;
};

接下来,要初始化结构,我正在读取这样的输入,在 function 定义中,使用scanf

void initRectangle(struct Geometry **object){
    scanf(SCANF_FMT_RECTANGLE, &((*object)->rectangle_corner1), &((*object)->rectangle_corner2), &((*object)->width), &((*object)->height));
    (*object)->isrectangle = true;
    (*object)->iscircle = false;
    (*object)->isquare = false;
    (*object)->isline = false;
}

同理,其他init函数也完成了。 其他2个功能是这样完成的:

void printGeometry(struct Geometry* object){
    if (object->iscircle == true){
        printf(PRINTF_FMT_CIRCLE, object->center1, object->center2, object->radius);
    }
    else if (object->isline == true){
        printf(PRINTF_FMT_LINE, object->x1, object->x2, object->y1, object->y2);
    }
    else if (object->isquare == true){
        printf(PRINTF_FMT_SQUARE, object->square_corner1, object->square_corner2, object->side);
    }
    else {
        printf(PRINTF_FMT_RECTANGLE, object->rectangle_corner1, object->rectangle_corner2, object->width, object->height);
    }
}

void freeGeometry(struct Geometry* object){
    free(object);
    object = NULL;
}  

我收到这条消息的分段错误:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  0x00007f3d6afb481f in _IO_vfscanf_internal (s=<optimized out>, 
    format=format@entry=0x402004 "%f %f %f %f", 
    argptr=argptr@entry=0x7fff2d49d5f0, errp=errp@entry=0x0) at vfscanf.c:2445

根据 seg fault 错误消息,我认为我的错误与结构的读取输入有关。 为什么会出现分段错误? 这个问题的正确方法是什么?

您应该在object中分配每个Geometry * 否则,您传递给initRectangle的指针本质上是垃圾值,因此取消引用它们会导致分段错误。

暂无
暂无

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

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