Thread: Freeing memory

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    8

    Freeing memory

    Hi,
    Below is a code that has been written so that I can compute the fibinacci sequence using threads based on user input at command line. The program has been written for a linux OS.
    There is a statement close to the exit of the program where I am trying to free the memory that I allocated to store the fibonacci sequence. Every time I try to free the memory using the free() system call, it gives me a "glibc detected" error AFTER printing the correct output. If I comment out the line where I am freeing the memory, there are no issues. Can anyone suggest, what I might be doing wrong?
    Thanks
    V

    Code:
    #include <pthread.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    int *myPtr;		//integer pointer to fibonacci sequence generated by fibonacci methode
    void *fibonacci(void *param);	//thread that generates the fibonacci sequence
    
    int main(int argc, char *argv[]){
     
      pthread_t tid;	//thread identifier
      pthread_attr_t attr;	//thread attributes
      int i;                //loop control
      int intValue = atoi(argv[1]);    //convert upper value from char to int
      //ensure that there are two arguments provided in the command line. (program name and fibonacci upper bound)
      if(argc != 2){
       fprintf(stderr, "argumenent count in the command line must be 2! program name and fibonacci upper bound value\n");
         return -1;
      }
    
      //ensure that fibonacci upper bound value is a positive integer value
      if(intValue < 0){
         fprintf(stderr, "fibonacci upper bound value must be greater than 0\n");
         return -1;
      }
    
      // allocate memory space for storing the fibonacci sequence
      myPtr = (int*) malloc(intValue + 2);
      if(myPtr == NULL){                 //Ensure sufficient memory. Exit if there is no memory available
          fprintf(stderr, "Unable to allocate memmory\n");
          return -1;
        }
    
      //initialize thread atttribute with default values
      pthread_attr_init(&attr);
      //create thread
      pthread_create(&tid, &attr, fibonacci, argv[1]);
    
      //wait for thread to exit
      pthread_join(tid, NULL);
    
      //print the sequence of integers pointed to by sequence pointer
      printf("The Fibonacci sequence are:\n");
      for(i = 0; i <= intValue; i++){
        printf("%d ", *myPtr);
        myPtr++;
         if(i + 1  % 21 == 0)                       //go to a new line after each 20th value
            printf("\n");
         }
      printf("\n\n");
      //  free(myPtr);
      // myPtr = NULL;
    }
    
    //Thread will begin control in this function
    void *fibonacci(void *param){
      int j;       //loop control integer
      int integerParam   = atoi(param);   //convert param to integer
      int sequence[integerParam + 1];
      sequence[0] = 0;
      if(integerParam > 0)
         sequence[1] = 1;
      if(integerParam > 1){
         for(j = 2; j <= integerParam; j++){
           sequence[j] = sequence[j-1] + sequence[j-2];
          }
      }
      // copy each value in the array over to the memory space pointed to by myPtr
      for(j = 0; j <= integerParam; j++)
        myPtr[j] = sequence[j];
      pthread_exit(0);   //exit thread
    }
    [Output]
    *** glibc detected *** ./jonathan: munmap_chunk(): invalid pointer: 0x084cd030 ***
    ======= Backtrace: =========
    /lib/libc.so.6(cfree+0x1bb)[0x6ffceb]
    ./jonathan[0x80487b2]
    /lib/libc.so.6(__libc_start_main+0xdc)[0x6a8e8c]
    ./jonathan[0x8048561]
    ======= Memory map: ========
    0036a000-0036b000 r-xp 0036a000 00:00 0 [vdso]
    00670000-0068a000 r-xp 00000000 68:01 4063261 /lib/ld-2.5.so
    0068a000-0068b000 r-xp 00019000 68:01 4063261 /lib/ld-2.5.so
    0068b000-0068c000 rwxp 0001a000 68:01 4063261 /lib/ld-2.5.so
    00693000-007d1000 r-xp 00000000 68:01 4063268 /lib/libc-2.5.so
    007d1000-007d3000 r-xp 0013e000 68:01 4063268 /lib/libc-2.5.so
    007d3000-007d4000 rwxp 00140000 68:01 4063268 /lib/libc-2.5.so
    007d4000-007d7000 rwxp 007d4000 00:00 0
    00808000-0081b000 r-xp 00000000 68:01 4063297 /lib/libpthread-2.5.so
    0081b000-0081c000 r-xp 00012000 68:01 4063297 /lib/libpthread-2.5.so
    0081c000-0081d000 rwxp 00013000 68:01 4063297 /lib/libpthread-2.5.so
    0081d000-0081f000 rwxp 0081d000 00:00 0
    00a87000-00a92000 r-xp 00000000 68:01 4063463 /lib/libgcc_s-4.1.2-20080825.so.1
    00a92000-00a93000 rwxp 0000a000 68:01 4063463 /lib/libgcc_s-4.1.2-20080825.so.1
    08048000-08049000 r-xp 00000000 68:02 21495810 /home/psblnx01/vbd1/Students/jonathan
    08049000-0804a000 rw-p 00000000 68:02 21495810 /home/psblnx01/vbd1/Students/jonathan
    084cd000-084ee000 rw-p 084cd000 00:00 0
    b7527000-b7528000 ---p b7527000 00:00 0
    b7528000-b7f2a000 rw-p b7528000 00:00 0
    b7f43000-b7f44000 rw-p b7f43000 00:00 0
    bffb8000-bffcd000 rw-p bffb8000 00:00 0 [stack]
    Aborted
    [\Output]

  2. #2
    {Jaxom,Imriel,Liam}'s Dad Kennedy's Avatar
    Join Date
    Aug 2006
    Location
    Alabama
    Posts
    1,065
    If you are free()ing in multiple threads, perhaps a use count and let the last one free() the memory?

  3. #3
    Registered User
    Join Date
    Jun 2008
    Posts
    17
    From the way your code looks, you seem to expect myPtr to be used as an int array. Which means, they way you allocated the memory for myPtr
    Code:
    myPtr = (int*) malloc(intValue + 2);
    is wrong because what you basically are doing is allocating intValue+2 bytes of memory. Based on that this code
    Code:
    for(j = 0; j <= integerParam; j++)
        myPtr[j] = sequence[j];
    is a buffer overflow. The usual way to allocate array is by using the calloc() function (do man calloc to find out more). Granted that many C/C++ reference materials do that to allocate memory for C-style strings, it doesn't mean it's necessarily the best way to do things.

    Second, the code below moves myPtr to a memory location that you didn't allocate:
    Code:
    for(i = 0; i <= intValue; i++){
        printf("%d ", *myPtr);
        myPtr++;
    .
    By the time the for loop is done, myPtr is now pointing to something else.

    C and C++ users who are well-versed in pointer arithmetic and the nuances of memory allocation can get away with code like what you did above. However, I suggest that you stay away from it for the sake of others who will sooner or later have to read your code. However, if you're really interested in how this code could be corrected let me know and I'll send it to you as a private message.

  4. #4
    Registered User
    Join Date
    Mar 2009
    Posts
    8
    [Quote]
    C and C++ users who are well-versed in pointer arithmetic and the nuances of memory allocation can get away with code like what you did above. However, I suggest that you stay away from it for the sake of others who will sooner or later have to read your code. However, if you're really interested in how this code could be corrected let me know and I'll send it to you as a private message. [\Quote]

    Thank you for the detailed reply. It helped a lot. I would like to learn the right way of doing this. I would appreciate your help in letting me know what the correct code would look like. Let me know what I should correct. Thanks
    [email protected]

  5. #5
    Registered User
    Join Date
    Jun 2008
    Posts
    17
    Okay, here's the stuff to fix your code as it stands so it'll work. As for funny pointer tricks, I'll post a link at a later time.

    First, change:
    Code:
    myPtr = (int*) malloc(intValue + 2);
    to
    Code:
    myPtr = (int*) calloc(intValue, sizeof(int));
    Second, change:
    Code:
    for(i = 0; i <= intValue; i++){
        printf("%d ", *myPtr);
        myPtr++;
    }
    to
    Code:
    for(i = 0; i < intValue; i++){
        printf("%d ", myPtr[i]);
    }
    I didn't run this through a compiler, so forgive me if it has a syntax error, or doesn't work as you expect to begin with.
    Last edited by pantherse; 10-28-2009 at 06:16 PM.

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by pantherse View Post
    The usual way to allocate array is by using the calloc() function (do man calloc to find out more).
    Why? The only difference between malloc and calloc, is that the latter runs through and tries to zero fill everything. I'm not sure why you think it's the "usual way" compared to malloc though.

    To the OP:

    I never use <= to walk an array. It's clearer to do this:
    Code:
    for( x = 0; x < SIZE; x++ )
    The size of the array should be SIZE, and you never try to access array[ SIZE ] because you aren't allowed to.


    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Jun 2008
    Posts
    17
    Quote Originally Posted by quzah View Post
    Why? The only difference between malloc and calloc, is that the latter runs through and tries to zero fill everything. I'm not sure why you think it's the "usual way" compared to malloc though.
    Let me restate, that's MY usual way. This is from the malloc/calloc manpage:
    void *
    calloc(size_t count, size_t size);
    The calloc() function contiguously allocates enough space for count objects that are size bytes of memory each and returns a pointer to the allocated memory.
    That's the reason why I prefer to use calloc() when allocating arrays. I find it clearer to read, and you don't run the risk if confusing what you're allocating for. I agree that
    Code:
    ptr = malloc(array_size * sizeof(int))
    and
    Code:
    ptr = calloc(array_size, sizeof(int))
    allocates the same amount of memory with the calloc() setting all values to zero.

    At the end of the day it's all about preferences. I just feel that it's better to err on readability than speed.
    Last edited by pantherse; 10-28-2009 at 10:20 PM.

  8. #8
    Registered User
    Join Date
    Jun 2008
    Posts
    17
    Quote Originally Posted by vbdave78 View Post
    I would like to learn the right way of doing this. I would appreciate your help in letting me know what the correct code would look like. Let me know what I should correct. Thanks
    [email protected]
    I finally got around to getting this to you: Keith's programming blog: C and C++ Array Intricacies It's not my best writing, so I would appreciate comments/questions.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. memory freeing function
    By johndoe in forum C Programming
    Replies: 4
    Last Post: 02-17-2006, 02:08 AM
  2. Freeing memory for non-pointer variables
    By SuperGodAntMan in forum C++ Programming
    Replies: 7
    Last Post: 02-11-2006, 01:30 AM
  3. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  4. memory allocation and freeing
    By Jase in forum Linux Programming
    Replies: 1
    Last Post: 05-25-2003, 06:26 AM
  5. freeing memory
    By mart_man00 in forum C Programming
    Replies: 1
    Last Post: 04-27-2003, 08:51 PM

Tags for this Thread