Question

I am getting a segmentation fault in my code. My code is:

#define STARTING_POINT 5
int main(int argc, char *argv[])
{
input(argc, argv);
parser(argc, argv);
drawingRooms();
return 0;
}


void drawingRooms(room roomInfo[6]) 
{
int rooms;
int i;
int positionX;
int positionY;
rooms = 0;
initscr();
noecho();
for(rooms = 0; rooms < 6; rooms++)
{
    switch(rooms)
    {
        case 0:
        for(i = 0; i <= roomInfo[rooms].length; i++);
        {
            move(STARTING_POINT + i, STARTING_POINT);
            printw("|");
        }
        break;
    }
}   
getch();
endwin();
}


void parser(int argc, char **argv)
{
FILE * rooms;
char * theString;
char * theToken;
int width;
int length;
int k;
int x;
int placeInt;
int posX;
int posY;
char a[ROOM_STRING_LENGTH];
item gold;
item monster;
item potion;
item hero;
item stairs;
room roomInfo[6];
rooms = fopen(argv[1], "r");

if(rooms == NULL)
{
    printf("error opening file\n");
}
x = 0;
while(fgets(a, ROOM_STRING_LENGTH, rooms) != NULL)
{ 

    theString = malloc((sizeof(char)*(strlen(a)+1)));
    strcpy(theString, a);

    for(theToken = strtok(theString, " "); theToken; theToken = strtok(NULL, " "))
    {
        sscanf(theToken, "%dX%d", &length, &width);
        roomInfo[x].roomNumber = x;
        roomInfo[x].width = width;
        roomInfo[x].length = length;

        if(theToken[0] == 'd')
        {
            switch(theToken[1])
            {
                case 'e':
                {
                    placeInt = theToken[2] - '0';
                    roomInfo[x].eastDoor = placeInt;
                    break;
                }
                case 'w':
                {
                    placeInt = theToken[2] - '0';
                    roomInfo[x].westDoor = placeInt;
                    break;
                }
                case 's':
                {
                    placeInt = theToken[2] - '0';
                    roomInfo[x].southDoor = placeInt;
                    break;
                }
                case 'n':
                {
                    placeInt = theToken[2] - '0';
                    roomInfo[x].northDoor = placeInt;
                    break;
                }
                default:
                {
                    break;
                } 
            }       
        }

        else if(theToken[0] == 'g' || theToken[0] == 'm' || theToken[0] == 'p' || theToken[0] == 'h')
        {
             k = 0;
             while(k <= (strlen(theToken)))
             {

                 switch(theToken[k])
                 {
                     case 'g':
                     posY = theToken[1] - '0';
                     posX = theToken[3] - '0';

                     gold.Xposition = posX;
                     gold.Yposition = posY;
                     break;

                     case 'm':
                     posY = theToken[1] - '0';
                     posX = theToken[3] - '0';

                     monster.Xposition = posX;
                     monster.Yposition = posY;
                     break;

                     case 'p':
                     posY = theToken[1] - '0';
                     posX = theToken[3] - '0';

                     potion.Xposition = posX;
                     potion.Yposition = posY;
                     break;

                     case 'h':
                     posY = theToken[1] - '0';
                     posX = theToken[3] - '0';

                     hero.Xposition = posX;
                     hero.Yposition = posY;                  
                     break;

                     case 's':
                     posY = theToken[1] - '0';
                     posX = theToken[3] - '0';

                     stairs.Xposition = posX;
                     stairs.Yposition = posY;   
                     break;
                 }
                 k++;
             }
        }
        else if(theToken == NULL)
        {
            printf("end of file");
        }
    }

    if(theToken == NULL)
    {
        printf("\n");
    }
    x++;
}
free(theString);
fclose(rooms);
}

and my struct is:

typedef struct 
{
int roomNumber;
int length;
int width;
int eastDoor;
int westDoor;
int southDoor;
int northDoor;
}room;

What i am trying to do is access the first struct in my array of structs, then do something with the information ive acquired. Whenever i run the following code, nothing is printed and i get a seg fault

Was it helpful?

Solution

A variable you create, remains alive until the corresponding closing curly bracket } of the opening curly bracket { before it.

Each pair of opening and closing curly brackets and the contents within { ... } are referred as code blocks, and with this definition, we can say that a variable remains alive within the code block it is declared.

You are declaring one roomsInfo[6] array inside the function parser, and it looks like you are hoping to be able to access it directly without doing anything from another function: drawingRooms

Things won't work out like that.

One another thing, a C compiler shouldn't be allowing you to call a function that asks for an argument, without an argument. So you shouldn't be able to make the call drawingRooms( ); at all, for void drawingRooms( room roomInfo[6] ) { ... } defined like that. In case it does allow, then it probably regards room roomInfo[6] as an un-initialized variable, like this:

    void drawingRooms(  )
    {
        room roomInfo[6];
        ...
    }

Anyway, what you should be doing is to feed the drawingRooms with an appropriate argument, which would be the address, the pointer to the first element of the array of 6 room structures; if you have declared its function like that.

To resolve this specific issue, you have two options, I'll start with the easy one:

1) Making roomInfo[6] a file-scope variable

By making the roomInfo[6] a global (file-scope) variable, the variable will live through the whole life-time of the programme, thus will be accessible from everywhere in the code. To do this:

  • delete the line room roomInfo[6]; inside the parser function
  • remove the argument room roomInfo[6] from the function drawingRooms
  • declare room roomInfo[6]; above everything else, above the main function

Like this:

    #define STARTING_POINT 5

    //somewhere above the roomInfo declaration, somewhere here
    //there has to be the typedef for the room structure,
    //either through the inclusion of a header file
    //or the typedef struct {...} room; itself

    room roomInfo[6];

    int main( ... )
    {
        ...
    ...

2) Pushing the pointer to the drawingRooms

To do this, you'll have to first allocate memory for the array of room structures yourself, so that it won't get killed automatically when the parser function ends; then return the pointer to the first element with the parser function, use that returned address while calling the drawingRooms function:

  • replace the line room roomInfo[6]; with room * roomInfo; in the parser function
  • allocate 6 room structure-worth memory for your rooms

Like this:

    roomInfo = calloc( 6, sizeof * roomInfo );
  • make sure you have included either <stdlib.h> or <malloc.h>, for the calloc call
  • add this line at the end of parser function: return roomInfo;
  • change the return value of parser function from void into room *
  • use this return value inside the main function while calling the drawingRooms function

Like this:

    //either like this:
    ...
        input( argc, argv );
        drawingRooms( parser( argc, argv ) );
    ...

    //or like this (allows you to free it inside main):
    ...
        room * roomInfo;
        input( argc, argv );
        roomInfo = parser( argc, argv );
        drawingRooms( roomInfo );
    ...
  • if your programme is to run further, make sure you free the allocated memory.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top