Reputation: 1398
I'm trying to implement a train structure in c. I have a struct called bogie and another called linked bogie. I'm having problems with how to refer to all components of these structures in the code. My main problems are:
-I get a seg fault while entering the bogie type
-Why is size of bogie 28? (char(1) +array(20) +int(4)=25)
-I want to confirm if there is a struct inside a struct,I need to malloc for every inner struct when i make an instance of the outer struct? Anyway to make this automatic.
-Am I over complicating the code? Is there a cleaner way to write this?
#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;
}
Upvotes: 0
Views: 101
Reputation: 148880
Mike already explained that the size of the struct was caused by padding. In your system, an int uses 4 bytes and is aligned on a address multiple of 4.
Your mallocs are correct, but you will have to consistently free the inner and outer struct when later removing a boogie.
But you have small errors in your code:
scanf("%c%s%d", ...)
will not do what you expect: the %c is likely to read the end of the previous line and not the first non blank character. You should use a %1s
for that, without forgotting a place for the null:
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);
will not work either: when the train contains only one boogie, you set traverse to null before testing anything. You should do:
while(traverse->link!=NULL) {
traverse = traverse->link;
}
in `print_traint, you forgot to move traverse. It should be:
while(traverse != NULL)
{
....
traverse = traverse->link;
count += 1;
}
Remember:
%c
is seldom used because it reads even non printable characters which are ignored by other formatsdo {...} while(...);
if less used than the simple while(...) {...}
because it runs its body at least once.Upvotes: 1