2016-10-26 3 views
-1

내가 C에 새로운 오전, 나는 단순히 스크립트를 아래와 같이 작성되었습니다C 점점 세분화 오류

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

typedef enum {FALSE, TRUE} bool; 

// item_t: information for a single item to be purchased 
typedef struct _item_t { 
    char name[50]; 
    int price; 
    int quantity; 
} item_t; 

// cart_t: information for the shopping cart 
typedef struct _cart_t { 
    item_t *items[10]; 
    int size; 
} cart_t; 

// Returns index of item with name `item_name` in the `items` array inside of `cart`. Returns -1 if not found. 
int find_item(cart_t *cart, const char* item_name) { 
    int i; 
    for(i=0;i<sizeof(*cart);++i){ 
     if(strcmp(cart->items[i]->name,item_name) == 0){ 
      return i; 
     } 
    } 

    if(i == sizeof(*cart) -1) 
     return -1; 
    return 0; 
} 

// Adds item to cart's items array, if the cart is not full. Returns `FALSE` if the cart is full, and returns `TRUE` otherwise. 
bool add_new_item(cart_t *cart, item_t *item) { 
    if(10 == cart->size) 
     return FALSE; 
    else{ 
     int i = cart->size; 
     cart->items[i] = item; 
     cart->size +=1; 
     return TRUE; 
    } 
} 

// Increases quantity by one of item with name `item_name` inside of `cart`, if such an item exists. 
void add_existing_item(cart_t *cart, const char* item_name) { 
    int i = find_item(cart,item_name); 
    if(i == -1) 
     return; 
    else{ 
     cart->items[i]->quantity += 1; 
    } 
} 

// Removes item with name from cart's items array. Returns a pointer to the removed item, and shifts the items to the right of the deleted item in the `items` array 
// left to fill in the gap. 
// If the item is not found, return NULL. 
item_t* remove_item(cart_t *cart, char *remove_me) { 
     item_t *p; 
     int j = 0; 
     int i = find_item(cart,remove_me); 
     if(i == -1) 
      return NULL; 
     else{ 

      if(i == cart->size-1){ 
       p = cart->items[i]; 
       cart->items[i] = NULL; 
      }else{ 
       p = cart->items[i]; 
       for(j=i;j<cart->size-1;++j){ 
        cart->items[j] = cart->items[j+1]; 
       } 
       cart->items[cart->size-1] = NULL; 
       cart->size -= 1; 
      } 
      return p; 
     } 
    } 

// Determines and returns the total cost of items in cart. 
int total_cost(cart_t *cart) { 
    int total; 
    int i; 
    for(i=0;i<sizeof(*cart);++i){ 
     total += cart->items[i]->quantity * cart->items[i]->price; 
    } 
    return total; 
} 

//print item's info and cost. 
void print_item_cost(item_t *item) { 
    printf("%s %d @ $%d = $%d\n", item->name, item->quantity, 
      item->price, (item->price * item->quantity)); 
} 

//print the shopping cart info 
void print_total(cart_t *cart) { 
    int i = 0; 
    int cost = 0; 

    printf("Number of Items: %d\n\n", num_items(cart)); 

    if (cart->size > 0) { 
     for (i = 0; i < cart->size; ++i) { 
      print_item_cost(cart->items[i]); 
     } 
    } 

    else { 
     printf("SHOPPING CART IS EMPTY\n"); 
    } 

    cost = total_cost(cart); 

    printf("\nTotal: $%d\n", cost); 
} 

//this function clears items in the cart 
void clear_cart(cart_t *cart) { 
    int i = 0; 
    for (i = 0; i < cart->size; i++) { 
     free(cart->items[i]); 
    } 
    cart->size = 0; 
} 

//a menu of options to manipulate the shopping cart 
void print_menu(cart_t *cart) { 
    char choice = ' '; 
    char name[50] = ""; 
    int price = 0; 
    int quantity = 0; 
    int i = 0; 
    char c = ' '; 
    item_t *item; 

    while(choice != 'q') { 

     printf("MENU\n"); 
     printf("a - Add item to cart\n"); 
     printf("r - Remove item from cart\n"); 
     printf("c - Change item quantity\n"); 
     printf("o - Output shopping cart\n"); 
     printf("q - Quit\n\n"); 

     while (choice != 'a' && 
       choice != 'r' && 
       choice != 'c' && 
       choice != 'o' && 
       choice != 'q') { 
      printf("Choose an option: "); 
      scanf(" %c", &choice); 
      printf("\n"); 
     } 

     switch (choice) { 
      case 'a': 
       while ((c = getchar()) != EOF && c != '\n'); 

       printf("ADD ITEM TO CART\n"); 
       printf("Enter the item name: "); 
       fgets(name, 50, stdin); 
       printf("\n"); 

       i = find_item(cart, name); 
       if (i != -1) { 
        printf("Item found. Updating quantity of item. \n"); 
        add_existing_item(cart, name); 

        choice = ' '; 
        printf("\n"); 
        break; 
       } 

       if (cart->size >= 10) { 
        printf("Cart full. Cannot add new item. \n"); 

        choice = ' '; 
        printf("\n"); 
        break; 
       } 

       printf("Enter the item price: "); 
       scanf("%d", &price); 
       printf("\n"); 

       printf("Enter the item quantity: "); 
       scanf("%d", &quantity); 
       printf("\n"); 


       item = (item_t*)malloc(sizeof(item_t)); 
       strcpy(item->name, name); 
       item->price = price; 
       item->quantity = quantity; 
       add_new_item(cart, item); 

       choice = ' '; 
       printf("\n"); 

       break; 

      case 'r': 
       while ((c = getchar()) != EOF && c != '\n'); 

       printf("REMOVE ITEM FROM CART\n"); 
       printf("Enter name of item to remove: "); 
       fgets(name, 50, stdin); 
       printf("\n"); 

       item = remove_item(cart, name); 
       if (item == NULL) { 
        printf("Item not found. \n"); 
       } 
       else { 
        printf("Item removed. \n"); 
        free(item); 
       } 

       choice = '\0'; 
       printf("\n"); 
       break; 

      case 'c': 

       while ((c = getchar()) != EOF && c != '\n'); 

       printf("CHANGE ITEM QUANTITY\n"); 
       printf("Enter the item name: "); 
       fgets(name, 50, stdin); 
       printf("\n"); 

       i = find_item(cart, name); 

       if (i == -1) { 
        printf("Item not found. \n"); 
        choice = ' '; 
        printf("\n"); 
        break; 
       } 

       printf("Enter the item price: "); 
       scanf("%d", &price); 
       printf("\n"); 


       printf("Enter the new quantity: "); 
       scanf("%d", &quantity); 
       printf("\n"); 

       update_item_in_cart(cart, name, price, quantity); 

       choice = '\0'; 
       printf("\n"); 

       break; 

      case 'o': 
       while ((c = getchar()) != EOF && c != '\n'); 
       printf("OUTPUT SHOPPING CART\n"); 
       print_total(cart); 
       choice = ' '; 
       printf("\n"); 
       break; 

     } 
    } 
    clear_cart(cart); 
} 

int main(){ 
    // malloc 
    cart_t *cart; 
    cart = (cart_t*)malloc(sizeof(cart_t)); 
    cart->size = 0; 

    print_menu(cart); 

    //free 
    free(cart); 
    return 0; 
} 

그것은 긴 보일 수도 있지만, 아이디어는 단순히, 그것은, 쇼핑 카트에 아이템을 시뮬레이션 항목 추가/항목 제거/수량 변경/현재 카트 정보 표시 명령을받습니다. 그러나 디버깅의 초기 단계에서 명령 창에서 다음을 수행 할 때 :

$ ./try 
MENU 
a - Add item to cart 
r - Remove item from cart 
c - Change item quantity 
o - Output shopping cart 
q - Quit 

Choose an option: a 

ADD ITEM TO CART 
Enter the item name: tira 

Segmentation fault (core dumped) 

세그먼트 오류가 발생합니다. 나는이 버그가 무엇이 될지 궁금하다. 나는 C에서 정말 새롭고 코드에서 포인터의 정확성에 대해 확신하지 못했다.

추신 : 답장을 보내 주셔서 감사합니다. 예, add_new_item 함수의 버그를 해결하는 데 도움이됩니다.

$ ./try 
MENU 
a - Add item to cart 
r - Remove item from cart 
c - Change item quantity 
o - Output shopping cart 
q - Quit 

Choose an option: a 

ADD ITEM TO CART 
Enter the item name: shoes 

Enter the item price: 1 

Enter the item quantity: 2 


MENU 
a - Add item to cart 
r - Remove item from cart 
c - Change item quantity 
o - Output shopping cart 
q - Quit 

Choose an option: r 

REMOVE ITEM FROM CART 
Enter name of item to remove: shoes 

Item removed. 

MENU 
a - Add item to cart 
r - Remove item from cart 
c - Change item quantity 
o - Output shopping cart 
q - Quit 

Choose an option: o 

OUTPUT SHOPPING CART 
Segmentation fault (core dumped) 
+0

두 함수에서 초기화되지 않은'int total'의 값을 사용하고 리턴합니다 (컴파일러 경고 참조). –

+0

또한'for (i = 0; i

답변

3

하나의 문제는 적어도 find_item 기능에 : 당신의 기능을해야 의미

. sizeof(*cart)은 카트의 실제 항목 수와 아무 관련이 없습니다. sizeof은 데이터 구조의 바이트 수를 반환합니다. 이 경우 최소 44 바이트입니다 (4 바이트 int 및 4 바이트 포인터라고 가정). 당신은 이런 식으로이 기능을 변경해야합니다 sizeof(*cart)와 카트 (cart->size)의 항목 수를 혼란, @Fang에서 언급 한 바와 같이

// Returns index of item with name `item_name` in the `items` array inside of `cart`. Returns -1 if not found. 
int find_item(cart_t *cart, const char* item_name) { 
    int i; 
    for(i=0;i<cart->size;++i){ 
     if(strcmp(cart->items[i]->name,item_name) == 0){ 
      return i; 
     } 
    } 

    return -1; // if we get here, then no items were found, so return -1. 
       // I don't understand your logic in returning 0, since 0 is a valid item index 
} 

이 코드 전반에 걸쳐 일반적인 실수이다. 이 작업은 항목을 반복 할 장소를 변경해야합니다.

+1

마찬가지로 cart Fang

2

분할 고장이 find_item 기능에 원인 코드의 문제, 당신은 sizeof를 사용 : 나는 remove_item을 디버깅 할 때 그러나,이 세그먼트 오류 다시 종료 명령 줄은 다음과 같다 키워드를 사용하여 장바구니의 size 속성을 사용해야합니다.

sizeof은 장바구니에있는 항목의 수를 size 속성에 저장하는 반면 카트 구조의 크기는 바이트로 표시합니다 (변경되지 않음).

// Returns index of item with name `item_name` in the `items` array inside of `cart`. Returns -1 if not found. 
int find_item(cart_t *cart, const char* item_name) { 
    int i; 
    for(i=0;i<cart->size;++i){ 
     if(strcmp(cart->items[i]->name,item_name) == 0){ 
      return i; 
     } 
    } 

    if(i == cart->size) 
     return -1; 
    return 0; 
}