You are here:

C/'malloc' function

Advertisement


Question
Hi!
My C code compiled on a MAC station gives me a segmentation fault when it tries to go through the malloc statement below:

static double *tempr;
int  j = 15

if (tempr == NULL) {
     tempr = (long double*) malloc( (size_t) j * sizeof (long double) );
}

What could be the problem?

Thanks!

Answer
Alex, there is nothing in the code you posted that would normally cause a seg fault. You should, however, make tempr a long double. It's very likely that the heap has become corrupted through a bad call to free, or by writing past the bounds of allocated memory. Memory can be allocated through strdup, realloc, valloc, or calloc so when I say malloc, I mean all of these.

Common problems are:
-freeing memory that you did not get from the heap, such as freeing a local array.
-freeing memory allocated by alloca
-moving the pointer returned from the heap, and then freeing it.
-writing past the end of allocated memory or (less likely) writing before the start of allocated memory.

Try running the program with a debugger. The debugger may catch the cause of the memory corruption. You may need to turn on specific memory tracking tools in your debugger, assuming it has them.

Try doing a review of your code and look for the common problems. Look for strcpy, memcpy, sprintf, memmove and check that they are not writing past the end of allocated memory. Look for pointer arithmetic being done on the pointer returned from malloc. The pointer returned from malloc should not be incremented, decremented, or otherwise changed.

As a debugging tool, try replacing all the free calls in your project with your own function myFree(void* ptr). At first, have myFree do nothing and see if the problem goes away.

A good trick is the have the pre-processor do the replacement for you. Then your source code does not actually change. On UNIX, I've used something like -Dfree=myFree in the compiler command.

I'm not familiar with MAC, but if you can determine the bounds of your heap then you can check each call to myFree to determine if the memory is heap memory.

On some UNIX systems, I've used this isPtrHeap function:
/******************************************************************
* A Pointer may point to a heap allocation if it is
* above the uninitailized data and under the program break point
*/
static int isPtrHeap(void* target)
{
   extern unsigned long _end;

   if (target >= (void*)&_end && target < sbrk(0))
   {
  return 1;
   }
  
   return 0;
}

According to http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/m...
Mac supports sbrk and end functions.

If you can stop your program with a debugger at the point where isPtrHeap returns 0, you can check the stack trace and see how the program got there.

The next level of debugging is to keep track of all allocated memory and check each free against the allocated list. This will tell you if you're freeing a pointer that has been moved since it was allocated. It can be used to check if writing out of bounds was done. The trick is to create your own versions of all memory allocation functions, and all error prone functions like strcpy, memcpy, etc. Do checks on all memory operations in your functions. Have the pre-processor replace all calls to memory functions with calls to your own functions. This is a lot of work, but if you do it you will have a library of functions that you can use for debugging other programs.

If you like, send me your program and I'll have a look at it. If it is not MAC specific, I might even be able to run it. You can send it to zlatko.c.help at gmail.com

Good luck.

C

All Answers


Answers by Expert:


Ask Experts

Volunteer


Zlatko

Expertise

No longer taking questions.

Experience

No longer taking questions.

Education/Credentials
No longer taking questions.

©2012 About.com, a part of The New York Times Company. All rights reserved.