2016-11-07 86 views
0

我試圖在c中實現一個列車結構。我有一個叫做轉向架的結構,另一個叫鏈接轉向架。我在如何在代碼中引用這些結構的所有組件時遇到問題。 我的主要問題是:c中的鏈接列表,struct結構,分段錯誤

-I獲得賽格故障而進入轉向架類型

- 爲什麼是轉向架28的大小? (char(1)+ array(20)+ int(4)= 25)

- 我想確認一個結構裏面是否有結構,我需要爲每個內部結構malloc做一個實例外部結構?無論如何,使自動。

-Am I over over the code?有沒有更清晰的方式來寫這個?

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

typedef struct 
{ 
    char name; 
    char type[20]; 
    int capacity; 
}BOGIE; 

struct LINKED_BOGIE 
{ 
    BOGIE* bogie_part_address; 
    struct LINKED_BOGIE* link; 
}; 

typedef struct LINKED_BOGIE LINKED_BOGIE; 


void print_train(LINKED_BOGIE* engine_address); 
void add_bogie(LINKED_BOGIE* engine_address); 


void add_bogie(LINKED_BOGIE* engine_address) 
{ 
    LINKED_BOGIE* traverse=engine_address; 
    LINKED_BOGIE* new_bogie_address=(LINKED_BOGIE*)malloc(sizeof(LINKED_BOGIE)); 
    new_bogie_ad:dress->bogie_part_address=(BOGIE*) malloc(sizeof(BOGIE)); 

    printf("Enter bogie name,type,capacity\n"); 
    scanf("%c%s%d",&(new_bogie_address->bogie_part_address->name),(new_bogie_address->bogie_part_address)->type,&((new_bogie_address->bogie_part_address)->capacity)); 


    do traverse=traverse->link; 
    while(traverse->link!=NULL); 

    traverse->link=new_bogie_address; 
    new_bogie_address->link=NULL; 
    print_train(engine_address); 

} 



void print_train(LINKED_BOGIE* engine_address) 
{ 

    LINKED_BOGIE* traverse=engine_address; 
    int count=0; 
    printf("This is the train\n"); 
    printf("----------------------------------------\n"); 


    do 
    { 
     printf("Bogie number:%d\n",count); 
     printf("Bogie name:%c\n",traverse->bogie_part_address->name); 
     printf("Bogie type:%s\n",traverse->bogie_part_address->type); 
     printf("Bogie capacity:%d\n",traverse->bogie_part_address->capacity); 
     printf("----------------------------------------\n"); 
    } 
    while(traverse->link!=NULL); 

} 

int main() 
{ 

    printf("linked bogie size:%lu\n",sizeof(LINKED_BOGIE)); 
    printf("bogie size:%lu\n",sizeof(BOGIE)); 

    LINKED_BOGIE* engine_address=(LINKED_BOGIE*)malloc(sizeof(LINKED_BOGIE)); 
    engine_address->bogie_part_address=(BOGIE*)malloc(sizeof(BOGIE)); 

    engine_address->bogie_part_address->name='E'; 
    strcpy(engine_address->bogie_part_address->type,"Engine"); 
    engine_address->bogie_part_address->capacity=1; 
    engine_address->link=NULL; 

    // print_train(engine_address); 


    int choice=0; 
    do 
    { 
     printf("Pick what you want to do:\n\ 
1)View the train\n\ 
2)Add a bogie\n\ 
3)Insert a bogie\n\ 
4)Remove a bogie\n\ 
5)Sort train\n\ 
6)Swap bogies\n\ 
7)Exit\n"); 

     scanf("%d",&choice); 

     switch (choice) 
     { 
      case 1:print_train(engine_address);break; 
      case 2:add_bogie(engine_address); 
     } 

    } 

    while(choice!=7); 




return 0; 

} 
+0

由於填充,大小爲28:即使只使用了一個,'char'也將佔用4個字節。如果將字符串設置爲21個字符,則大小可能會跳到32位。這是因爲您編譯的CPU具有32位數據總線,所以當數據項在32位字邊界上對齊時,訪問速度最快。編譯器上可能會有一個'pack'雜注或屬性語言擴展,它可以刪除未使用的字節,但會減慢對該結構的所有訪問。 –

回答

1

Mike已經解釋過結構的大小是由填充引起的。在你的系統中,一個int使用4個字節並且在4的地址倍數上對齊。

你的malloc是正確的,但是當你以後移除一個布吉時,你將不得不一直釋放內部和外部結構。

但你必須在你的代碼的小錯誤:

  • scanf("%c%s%d", ...)你期望的事情:%C是可能閱讀前行的末尾,而不是第一個非空字符。您應該使用一個%1s,沒有forgotting一個地方空:

    char name[2]; 
    ... 
    scanf("%1s%19s%d",name,(new_bogie_address->bogie_part_address)->type, 
        &((new_bogie_address->bogie_part_address)->capacity)); 
    new_bogie_address->bogie_part_address->name = name[0]; 
    
  • do traverse=traverse->link; while(traverse->link!=NULL);將不起作用或者:當列車只包含一個布吉,你測試任何事情之前橫向設置爲null。你應該這樣做:

    while(traverse->link!=NULL) { 
        traverse = traverse->link; 
    } 
    
  • in`print_traint,你忘了移動遍歷。它應該是:

    while(traverse != NULL) 
    { 
        .... 
        traverse = traverse->link; 
        count += 1; 
    } 
    

記住:

  • %c很少使用,因爲它讀取它們由其他格式忽略甚至非打印字符
  • do {...} while(...);如果比簡單while(...) {...}少用因爲它至少運行過一次。