Question

I have been looking at creating a circularly linked list in C. The only problem I am not sure why this is creating a segmentation fault. From the print statements, the program works until the next pointers in each of the stage nodes are set. Would be appreciated if someone could help me out. Thanks

typedef struct stage stage;

/* data structure to store stage information */
struct stage
{
    char name[21]; /* stage name */
    stage* next;   /* pointer to next stage */
    int ncoins;    /* number of coins in the stage */
    int npipes;    /* number of pipes in the stage */
};


stage * create_stage(char * line)
{
    char * name; 
    int npipes;
    int ncoins;

    sscanf(line, "%s %d %d",name, &npipes, &ncoins);

    printf("Name: %s NCoins:%d NPipes:%d\n",name, ncoins,npipes);

    stage * s = malloc(sizeof(stage *));
    strncpy(s->name,name,MAX_NAME_LEN);
    s->ncoins = ncoins;
    s->npipes = npipes;

    printf("S Has: Name: %s NCoins:%d NPipes:%d\n",s->name, s->ncoins,s->npipes);


    return s;
}

stage * find_stage(stage * root, char * str)
{
    //Check that root is not null
    if(root == 0){
        return 0;
    }
    //Check the root is equal to the string
    if(strncmp(root->name, str, strlen(str))){
        return root;
    }
    stage * current = root;

    //Check until it has come full circle.
    while(current != root){
        if(strncmp(root->name, str, strlen(str))){
            return current;
        }
        current = current->next;
    }
    //Return nothing 
    return 0;
}


int main(void)
{
    //Game Settings
    char * stage1 = "garden 1 2";
    char * stage2 = "hallway 1 4";
    char * stage3 = "throneroom 2 8";

    printf("Made strings\n");

    //First node of the list
    stage * stg1 = create_stage(stage1);
    stage * stg2 = create_stage(stage2);
    stage * stg3 = create_stage(stage3);

    printf("Created stages\n");

    printf("Stage 1\nName: %s nPipes: %d nCoins: %d\n",stg1->name,stg1->npipes,stg1->ncoins);
    printf("Stage 2\nName: %s nPipes: %d nCoins: %d\n",stg2->name,stg2->npipes,stg2->ncoins);
    printf("Stage 3\nName: %s nPipes: %d nCoins: %d\n",stg3->name,stg3->npipes,stg3->ncoins);

    stg1->next = stg2;
    stg2->next = stg3;
    stg3->next = stg1;

    printf("stages connected");

    stage * foundStage = find_stage(stg1, "throneroom");


    free(stg1);
    free(stg2);
    free(stg3);


    return 0;

}
Was it helpful?

Solution

Change

char * name; 

to

char name[MAX_NAME_LEN] ; 

When you use sscanf, name must point to something. If you declare char *name, name points nowhere.

and change

stage * s = malloc(sizeof(stage*));

to

stage * s = malloc(sizeof(stage));

You need the size of the structure stage (sizeof(stage)) and not the size of a pointer to stage (sizeof(stage*)). When you use sizeof(stage*), you dont allocate enough memory, then when you fill the newly allocated stage, you overwrite memory that does not belong to you and from then on you will get undefined behaviour (anything can happen).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top