아하 로고
검색 이미지
생활꿀팁 이미지
생활꿀팁생활
생활꿀팁 이미지
생활꿀팁생활
파란비둘기109
파란비둘기10920.06.27

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;

}

55글자 더 채워주세요.
답변의 개수3개의 답변이 있어요!
  • 안녕하세요.

    문의하신 코드에 구현상에 몇가지 문법 오류가 존재하여 하나씩 설명드리겠습니다.

    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;

    }