Thread: segmentation fault when using char*[] (please help)

  1. #1
    Registered User
    Join Date
    Oct 2011
    Posts
    6

    segmentation fault when using char*[] (please help)

    Hi guys this is my first post here,
    I am trying to make a c program that reads a text file that is formatted like this
    0 human
    1 cat
    2 dog
    3 rat
    ect….
    So what I am trying to do is put them into an array using the number as the array index and the string as the value.
    I will give include the parts that I think would be necessary in solving this problem.

    char* memoryBuffer[maxPageNumber - 1];
    initBufferFile = fopen("init_buffer_pages.dat", "rt");


    //I have used fgets to read each line from a file
    fgets(fileInputBuffer, 4100, initBufferFile) == NULL)

    //Then used sscanf to separate the number and the string from each line
    (sscanf( fileInputBuffer, "%s %s", &currentNumber, &currentContents) == 2 )

    //if I print the current Number and current contents like this it works fine.
    printf("[%d](%s)\n", currentNumber, &currentContents);

    but when I put the contents in the page array like this
    memoryBuffer[currentNumber] = currentContents;

    and try to print the array item like
    printf(memoryBuffer[0]);
    or
    printf(&memoryBuffer[0]);

    it gives a segmentation fault when it runs.
    Im guessing its got something to do with the char*[] or the printf’s but im not sure.

    If anyone could give me any help It would be greatly appreated.
    Cheers

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    I'm guessing you should just post your actual code between [code][/code] tags.

    Without seeing the whole program, segfault diagnostics are a crap-shoot.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    Where is the definition of currentContents?

  4. #4
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    Code:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <ctype.h>
    #include <stdbool.h>
     
    void *threadMethod(void *threadNumber)
    {
       //cout << "Hello from thread: " + (int)threadNumber;
       printf("Hello from thread: %d \n", (int)threadNumber);
     
       //_exit(0);
    }
    int main(int argc, char* argv[])
    {
     
       FILE *initBufferFile;
       int numOfThreads = atoi(argv[1]);
       //int numOfThreads = 3;
       int check;
     
       printf("Number of threads = %d \n", numOfThreads);
     
       pthread_t clientArray[numOfThreads];
       int i;
     
       //create all client threads.
       for(i = 0; i < numOfThreads; i++)
       {
          printf("Creating thread: %d \n", i);
          check = pthread_create(&clientArray[i], NULL, threadMethod, (void *)i);
     
          if(check != 0)
          {
             printf("Error code for creating thread: %d is %d", i, check);
             _exit(-1);
          }
       }
     
       //join all the threads
       for(i = 0; i < numOfThreads; i++)
       {
          pthread_join(clientArray[i], NULL);
       }
     
       //initialise memory buffer
     
       initBufferFile = fopen("init_buffer_pages.dat", "rt");
       if(initBufferFile == 0)
       {
          printf( "Could not open file\n" );
       }
     
       int x;
       char* emptyArray;
       char fileInputBuffer[4100];
     
       i = 0;
       int currentNumber;
       char* currentContents;
       bool looping = true;
       bool readingLine = true;
     
     
       //while(fgets(fileInputBuffer, 4100, initBufferFile) != NULL)
       int loopNum = 1;
       char* test;
     
       //Find size of memory buffer
       int maxPageNumber = 0;
       while(looping)
     
     
          if (fgets(fileInputBuffer, 4100, initBufferFile) == NULL)
          {
             looping = false;
          }
          else
          {
             if(sscanf( fileInputBuffer, "%s %s", &test, &currentContents) == 2 )
    {
                currentNumber = (int)test;
                currentNumber = currentNumber - 48;
                if(currentNumber > maxPageNumber)
                {
                   maxPageNumber = currentNumber;
                }
             }
          }
     
       char* memoryBuffer[maxPageNumber - 1];
       printf("array[%d] has been made", maxPageNumber - 1);
     
       //reset the file, and read in initial pages
       initBufferFile = fopen("init_buffer_pages.dat", "rt");
       looping = true;
     
       while(looping)
     
       {
          if (fgets(fileInputBuffer, 4100, initBufferFile) == NULL)
          {
             looping = false;
          }
          else
          {
             if(sscanf( fileInputBuffer, "%s %s", &test, &currentContents) == 2 )
             {
                currentNumber = (int)test;
                currentNumber = currentNumber - 48;
                memoryBuffer[currentNumber] = currentContents;
     
                printf("[%d](%s)\n", currentNumber, &currentContents);
                printf("contnerdS::: %s \n",  &currentContents);
     
                memoryBuffer[currentNumber] = currentContents;
               // printf("TEST: %s ",&memoryBuffer[0]);
     
             }
     
    }
    printf("firstArrayItem: %s", memoryBuffer[0]);
    }
       return 0;
       }

  5. #5
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    ok i have put the full code up, current contents is: char* currentContents;

  6. #6
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    There is no memory associated with currentContents. You need a malloc. (but don't forget to free it!)

  7. #7
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    ok i have never used mallac and am quite new to c, but I have done a lot of java.
    Can you tell me were i would use mallac.
    Thanks so much for your help

  8. #8
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    Code:
    currentContents = malloc(100);
    You can now read upto 100 bytes into currentContents (or a string of 99).

    But once assigned to the memoryBuffer, you will need to do a new malloc for the next line.

    Maybe if it is a fixed length you should consider using a fixed sized array for currentContents, and a fixed two dimensional array for memoryBuffer and memcpy currentContents into memoryBuffer rather than assign. That way much less memory considerations for you.

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Code:
             if(sscanf( fileInputBuffer, "%s %s", &test, &currentContents) == 2 )
    {
                currentNumber = (int)test;
                currentNumber = currentNumber - 48;
    I'm going to assume that the first field of your input line is an int, in which case, use %d

    Second, as already pointed out, allocate some space.
    The very easy thing to do is simply say
    char currentContents[4100];
    to match the input buffer size.

    > //reset the file, and read in initial pages
    > initBufferFile = fopen("init_buffer_pages.dat", "rt");
    Or just rewind(initBufferFile)

    > memoryBuffer[currentNumber] = currentContents;
    Now this just results in all your lines pointing to the same buffer.
    You need to call malloc() to allocate space for each line you've read in.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    Ok i have done malloc for the currentContents and the arrays, and also added another array to read the strings from the text file into. I have also made a few other changes to the program.
    how ever when i print the array, every value is the same. (human). So it is reading the first value and inserting it into every part of the array.
    Code:
    #include <stdio.h>
    #include <pthread.h>
    #include <unistd.h>
    #include <string.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <ctype.h>
    #include <stdbool.h>
     
    void *threadMethod(void *threadNumber)
    {
       //cout << "Hello from thread: " + (int)threadNumber;
       printf("Hello from thread: %d \n", (int)threadNumber);
     
       //_exit(0);
    }
    int main(int argc, char* argv[])
    {
     
       FILE *initBufferFile;
       int numOfThreads = atoi(argv[1]);
       //int numOfThreads = 3;
       int check;
     
       printf("Number of threads = %d \n", numOfThreads);
     
       pthread_t clientArray[numOfThreads];
       int i;
     
       //create all client threads.
       for(i = 0; i < numOfThreads; i++)
       {
          printf("Creating thread: %d \n", i);
          check = pthread_create(&clientArray[i], NULL, threadMethod, (void *)i);
     
          if(check != 0)
          {
             printf("Error code for creating thread: %d is %d", i, check);
             _exit(-1);
          }
       }
    //join all the threads
       for(i = 0; i < numOfThreads; i++)
       {
          pthread_join(clientArray[i], NULL);
       }
     
       //initialise memory buffer
     
       initBufferFile = fopen("init_buffer_pages.dat", "rt");
       if(initBufferFile == 0)
       {
          printf( "Could not open file\n" );
       }
     
       int x;
       char* emptyArray;
       char fileInputBuffer[4100];
     
       i = 0;
       int currentNumber;
       char* currentContents;
       //currentContents = malloc(100);
     
       bool looping = true;
       bool readingLine = true;
     
     
       //while(fgets(fileInputBuffer, 4100, initBufferFile) != NULL)
       char* test;
     
       //Find size of memory buffer
       int maxPageNumber = 0;
       while(looping)
     
     
          if (fgets(fileInputBuffer, 4100, initBufferFile) == NULL)
          {
             looping = false;
          }
          else
          {
    if(sscanf( fileInputBuffer, "%s %s", &test, &currentContents) == 2 )
             {
                currentNumber = (int)test;
                currentNumber = currentNumber - 48;
                if(currentNumber > maxPageNumber)
                {
                   maxPageNumber = currentNumber;
                }
             }
          }
     
       char* memoryBuffer[maxPageNumber - 1];
       printf("array[%d] has been made", maxPageNumber - 1);
     
       //reset the file, and read in initial pages
       initBufferFile = fopen("init_buffer_pages.dat", "rt");
       looping = true;
     
     
       memoryBuffer[0] = malloc(100);
        memoryBuffer[1] = malloc(100);
         memoryBuffer[2] = malloc(100);
          memoryBuffer[3] = malloc(100);
     memoryBuffer[4] = malloc(100);
     
     
     
     
     
    char* testArray[5];
    int loopNum = 0;
    testArray[0] = malloc(100);
    testArray[1] = malloc(100);
    testArray[2] = malloc(100);
    testArray[3] = malloc(100);
    testArray[4] = malloc(100);
     
       while(looping)
    {
          //currentContents = 0;
          currentContents = malloc(100);
          memoryBuffer[loopNum] = malloc(100);
     
          //currentContents = "";
     
          if (fgets(fileInputBuffer, 4100, initBufferFile) == NULL)
          {
             looping = false;
          }
          else
          {
             //if(sscanf( fileInputBuffer, "%s %s", &test, &currentContents) == 2 )
             if(sscanf( fileInputBuffer, "%s %s", &test, testArray[loopNum]) == 2 )
             {
                currentNumber = (int)test;
                currentNumber = currentNumber - 48;
     
               printf("LOOP(%d) CURRENT#(%d) TESTARRAY(%s)\n",loopNum, currentNumber, testArray[loopNum]);
     
                memoryBuffer[currentNumber] = testArray[loopNum];
     
               // printf("[%d](%s)\n", currentNumber, &currentContents);
               // printf("contnerdS::: %s \n",  &currentContents);
     
                //memoryBuffer[currentNumber] = (char *)malloc(sizeof(char*));
     
               // memoryBuffer[currentNumber] = currentContents;
               // printf("TEST: %s ",&memoryBuffer[0]);
     
             }
     
          }
          loopNum++;
    }
     
    printf("Printing Array\n-------------");
    for(i = 0; i < maxPageNumber; i++)
    {
     
       printf("[%d] %s\n", i,memoryBuffer[0]);
    }
    //free(currentContents);
     
       return 0;
       }

  11. #11
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    oh god, sorry guys
    i just realised the printf("[%d] %s\n", i,memoryBuffer[0]);
    Thanks so much for the information on malloc, you have been so helpful

  12. #12
    Registered User
    Join Date
    Oct 2011
    Posts
    6
    That's OK.

    malloc(100) was just an example by the way, Salem is right 4100 seems to be the number you should be going for.

    There's too many mallocs going on in your second code post by far, you want only 1 new block of 4100 for every sscanf call, so that sscanf can write into a new block of memory. If it's successful, then assign that new block to memoryBuffer, otherwise free it (the else part of the if(scanf...==2)).

    As for freeing all at the end, (if you don't want a memory leak), loop through memoryBuffer calling free on each entry if it is not NULL. But you MUST initialise all entries to NULL after declaration for this to work.

  13. #13
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,661
    Code:
             if(sscanf( fileInputBuffer, "%s %s", &test, testArray[loopNum]) == 2 )
             {
                currentNumber = (int)test;
                currentNumber = currentNumber - 48;
    You're seriously abusing test here!
    If it's an int (as it seems to be), then just have
    int currentNumber;
    and
    if(sscanf( fileInputBuffer, "%d %s", &currentNumber, testArray[loopNum]) == 2 )
    and be done.


    Generally,
    Code:
    char temp[4100];
    while ( fscanf( fileInputBuffer, "%d %s", &currentNumber, temp) == 2 ) {
      memoryBuffer[currentNumber] = malloc( strlen(temp) + 1 );  // alloc space for the string we read
      if ( memoryBuffer[currentNumber] != NULL ) {
        strcpy( memoryBuffer[currentNumber], temp );  // make a copy of it
      } else {
        // complain about out of memory
      }
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Segmentation fault when appending to strings (char *)
    By LanguidLegend in forum C Programming
    Replies: 15
    Last Post: 02-24-2011, 07:35 PM
  2. Replies: 8
    Last Post: 12-08-2009, 02:47 AM
  3. Segmentation fault with structs and char pointers
    By Keybone in forum C++ Programming
    Replies: 20
    Last Post: 01-17-2004, 01:36 PM
  4. Segmentation Fault
    By Segmy in forum C Programming
    Replies: 1
    Last Post: 02-20-2003, 07:35 AM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM