在这个涉及结构和指针的 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
示例输出:
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
我需要编写函数。
我尝试了什么:
我写了一个结构,用一些 bool 变量来指示正在考虑哪个几何项目:
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;
};
接下来,为了初始化结构,我在函数定义中使用 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
根据段错误消息,我认为我的错误与结构的读取输入有关。为什么会出现分段错误?解决这个问题的正确方法是什么?
您应该对 object
中的每个 Geometry *
进行 malloc。否则,您传递给 initRectangle
的指针本质上是垃圾值,因此取消引用它们将导致分段错误。
我正在处理 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
示例输出:
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
我需要编写函数。
我尝试了什么:
我写了一个结构,用一些 bool 变量来指示正在考虑哪个几何项目:
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;
};
接下来,为了初始化结构,我在函数定义中使用 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
根据段错误消息,我认为我的错误与结构的读取输入有关。为什么会出现分段错误?解决这个问题的正确方法是什么?
您应该对 object
中的每个 Geometry *
进行 malloc。否则,您传递给 initRectangle
的指针本质上是垃圾值,因此取消引用它们将导致分段错误。