c 세그멘테이션 오류 동적할당 문제
무엇이 문제일까요ㅜㅜ 계속 동적할당할때만 세그멘테이션 오류가 나네요..
#include <stdio.h>
#include <stdlib.h>
typedef struct inventory
{
char* name;
int quantity;
double price;
struct inventory* next_inventory;
} invent;
int main()
{
invent *one;
invent *two;
invent *three;
one = (invent*)calloc(4, sizeof(invent));
two = (invent*)calloc(4, sizeof(invent));
three = (invent*)calloc(4, sizeof(invent));
printf("첫 번째 재고의 정보를 입력하시오\n");
printf("이름: ");
scanf("%s", &one[0].name);
printf("수량: ");
scanf("%d", &one[1].quantity);
printf("가격: ");
scanf("%d", &one[2].price);
one->next_inventory = two;
printf("두 번째 재고의 정보를 입력하시오\n");
printf("이름: ");
scanf("%s", &two[0].name);
printf("수량: ");
scanf("%d", &two[1].quantity);
printf("가격: ");
scanf("%d", &two[2].price);
two->next_inventory = three;
printf("세 번째 재고의 정보를 입력하시오\n");
printf("이름: ");
scanf("%s", &three[0].name);
printf("수량: ");
scanf("%d", &three[1].quantity);
printf("가격: ");
scanf("%d", &three[2].price);
printf("%s, %d, %d\n", one->name, one->quantity, one->price);
printf("%s, %d, %d\n", one->nextinventory->name, one->nextinventory->quantity, one->next_inventory->price);
printf("%s, %d, %d\n", one->nextinventory->nextinventory->name, one->nextinventory->nextinventory->quantity, one->nextinventory->nextinventory->price);
free(one);
free(two);
free(three);
return 0;
}
안녕하세요.
문의하신 코드에 구현상에 몇가지 문법 오류가 존재하여 하나씩 설명드리겠습니다.
1. inventory 구조체 내 "name" 변수에 사용자로부터 입력 받은 값을 저장하기 위해선
사용자로부터 입력 받기 전, 메모리 동적 할당 과정이 필요한데 이부분이 생략되어 있습니다.
메모리 동적 할당을 받아 strcpy() 함수를 이용해도 되고, 간단하게 char * 형 name 변수를 아래와 같이 정적 배열로 선언하여 해결 가능합니다.
typedef struct inventory { char name[20]; // char * name; ... }2. scanf()로 invent 구조체 변수에 대한 값을 입력 받을 때, 의도하지 않은 Index를 참조하여 입력받고 있습니다.
"one"을 예로 들면, "one[0]"의 name, quantity, price 멤버번수를 참조하여 입력받아야 합니다.
"one[0]"에 대해 수정한 코드를 예로들면,
printf("첫 번째 재고의 정보를 입력하시오\n"); printf("이름: "); scanf("%s", &one[0].name); printf("수량: "); scanf("%d", &one[0].quantity); // &one[1].quantity (X) printf("가격: "); scanf("%d", &one[0].price); // &one[2].price (X)3. printf()를 통해 출력할 때, 출력 문법이 잘못되었습니다.
"one"을 예로들면, 4개의 inventory형으로 메모리가 동적할당 되었기 때문에 정확한 "one"의 Index가 참조되어야 합니다.
아래 코드를 보면, "one"의 몇 번째 Index에 참조해야하는지 컴파일러는 알 수 없기 때문에 각각의 멤버변수에도 접근 할 수 없습니다.
printf("%s, %d, %d\n", one->name, one->quantity, one->price);"one[0]"에 대한 수정한 코드를 예로들면 다음과 같습니다.
printf("%s, %d, %d\n", one[0].name, one[0].quantity, one[0].price);4. 다음 inventory 구조체를 가리키는 "next_inventory" 관련 코드는 위에서 언급한 것과 같이 참조하려는 배열의 정확한 Index가 참조되어야 합니다.
one[0].next_inventory = &two[0]; // 혹은 one[0].next_inventory = two; 와 같이 사용가능한데, 이럴 경우 one[0].next_inventory가 참조하는 two는 two[0]가 됩니다.5. 마지막으로 "one"에서 가리키는 "next_inventory"는"one"의 정확한 Index를 지정하여, 확인해 볼 수 있습니다.
정확한 Index 참조하기 전(잘못된 코드)
printf("%s, %d, %d\n", one->nextinventory->name, one->nextinventory->quantity, one->next_inventory->price);정확한 Index를 참조하여 출력
printf("%s, %d, %d\n", one[0].nextinventory->name, one[0].nextinventory->quantity, one[0].next_inventory->price);위와 같은 문법 오류와 의도하지 않은 코드의 동작이 문제의 원인이었습니다.
좋은 하루 되세요 :)
안녕하세요.
아래쪽에 compile이 안되는 nextinventory부분을 간단히 수정하셔야 하구요, 이 부분 수정이후에
segment fault가 뜨는 이유는
char* name;때문입니다.
one = (invent*)calloc(4, sizeof(invent));와 같이 one에 대해서 메모리 할당을 해주셨지만,
그 invent구조체 안에 있는 char *에 대해서는 memory할당이 되지 않았습니다.
따라서 별도로 one.name = calloc(20, sizeof(char)); 이렇게 해주시거나, 간단히 고치실거라면, invent구조체를 아래와 같이 바꾸시며 됩니다.
typedef struct inventory { char name[20]; int quantity; double price; struct inventory* next_inventory; } invent;이렇게 20자를 받아들이는 고정 크기로 만들어서 시험해 보시면 segment fault가 뜨지 않을것입니다.
아래와 같이 코드 작성하여서 에러가 발생하시지 않을거 같습니다.
#include <stdio.h>
#include <stdlib.h>
typedef struct inventory
{
char name[100];
int quantity;
double price;
struct inventory* nextinventory;
} invent;
int main()
{
invent *one;
invent *two;
invent *three;
one = (invent*)calloc(1, sizeof(invent));
two = (invent*)calloc(1, sizeof(invent));
three = (invent*)calloc(1, sizeof(invent));
printf("첫 번째 재고의 정보를 입력하시오\n");
printf("이름: ");
scanf("%s", &one->name);
printf("수량: ");
scanf("%d", &one->quantity);
printf("가격: ");
scanf("%d", &one->price);
one->nextinventory = two;
printf("두 번째 재고의 정보를 입력하시오\n");
printf("이름: ");
scanf("%s", &two->name);
printf("수량: ");
scanf("%d", &two->quantity);
printf("가격: ");
scanf("%d", &two->price);
two->nextinventory = three;
printf("세 번째 재고의 정보를 입력하시오\n");
printf("이름: ");
scanf("%s", &three->name);
printf("수량: ");
scanf("%d", &three->quantity);
printf("가격: ");
scanf("%d", &three->price);
printf("%s, %d, %d\n", one->name, one->quantity, one->price);
printf("%s, %d, %d\n", one->nextinventory->name, one->nextinventory->quantity, one->nextinventory->price);
printf("%s, %d, %d\n", one->nextinventory->nextinventory->name, one->nextinventory->nextinventory->quantity, one->nextinventory->nextinventory->price);
free(one);
free(two);
free(three);
return 0;
}