C Board  

Go Back   C Board > General Programming Boards > C Programming

Reply
 
LinkBack Thread Tools Display Modes
Old 10-27-2009, 11:42 AM   #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]
vbdave78 is offline   Reply With Quote
Old 10-27-2009, 12:02 PM   #2
Jaxom's & Imriel's Dad
 
Kennedy's Avatar
 
Join Date: Aug 2006
Location: Alabama
Posts: 801
If you are free()ing in multiple threads, perhaps a use count and let the last one free() the memory?
Kennedy is offline   Reply With Quote
Old 10-27-2009, 12:47 PM   #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.
pantherse is offline   Reply With Quote
Old 10-27-2009, 01:35 PM   #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
vbdave78@yahoo.com
vbdave78 is offline   Reply With Quote
Old 10-28-2009, 05:01 PM   #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.
pantherse is offline   Reply With Quote
Old 10-28-2009, 05:09 PM   #6
+++ OK NO CARRIER
 
quzah's Avatar
 
Join Date: Oct 2001
Posts: 10,259
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.
__________________
Hundreds of thousands of dipshits can't be wrong.


Are you up for the suck?
quzah is offline   Reply With Quote
Old 10-28-2009, 06:26 PM   #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:
Quote:
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.
pantherse is offline   Reply With Quote
Old 11-18-2009, 12:56 PM   #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
vbdave78@yahoo.com
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.
pantherse is offline   Reply With Quote
Reply

Tags
code, output

Thread Tools
Display Modes

Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
memory freeing function johndoe C Programming 4 02-17-2006 02:08 AM
Freeing memory for non-pointer variables SuperGodAntMan C++ Programming 7 02-11-2006 01:30 AM
pointers InvariantLoop C Programming 13 02-04-2005 09:32 AM
memory allocation and freeing Jase Linux Programming 1 05-25-2003 06:26 AM
freeing memory mart_man00 C Programming 1 04-27-2003 08:51 PM


All times are GMT -6. The time now is 10:27 PM.


Powered by vBulletin® Version 3.8.1
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.0 RC2

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22