Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

farmerdoug

macrumors 6502a
Original poster
Sep 16, 2008
541
0
Code:
float *u;
printf("here %d\n", n);
	if ( !( u = (float *)calloc (2*n,sizeof (float)) ))
		printf( "calloc failed\n");
	
	printf("2here\n");
The first print statement tells me that n is 175;neither calloc failed or 2here is printed.
The code compiles but I get a checksum error for freed pointer when I run.

Just a clue as to what's going on or how to debug this.
Thanks.
 
What exactly am I looking for? It looks like I've confined the error to a single line?
thanks
 
You might want to consider freeing the memory when you're done with it (remember, C does not have built in garbage collection by default like Java does). You should also look at the value of u when stepping through your loop with a breakpoint to make sure it points to a valid address and not a null pointer.

An additional reference:
http://linux.die.net/man/3/calloc
 
The memory does get freed. As does other memory in the code and the if statement checks for a valid pointer. I'll check the link later. Thanks.
Code:
void spline(float x[], float y[], int n, float yp1, float ypn, float y2[])
{
	int i,k;
	float p,qn,sig,un,*u;
	
	printf("here %d\n", n);
	if ( !( u = (float *)calloc (2*n,sizeof (float)) ))
		printf( "calloc failed\n");
	
	printf("2here\n");
	if (yp1 > 0.99e30) //The lower boundary condition is set either to be "natural"
		y2[0]=u[0]=0.0; 
	else {				//or else to have a specified first derivative.
		y2[0] = -0.5;
		u[0]=(3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yp1);
	}
	for (i=1;i<=n-2;i++) {		//This is the decomposition loop of the tridiagonal algorithm.	y2 and u are used for temporary
		//storage of the decomposed factors.
		sig=(x[i]-x[i-1])/(x[i+1]-x[i-1]);
		p=sig*y2[i-1]+2.0;
		y2[i]=(sig-1.0)/p;
		u[i]=(y[i+1]-y[i])/(x[i+1]-x[i]) - (y[i]-y[i-1])/(x[i]-x[i-1]);
		u[i]=(6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p;
	}
	
	n = n-1;
	if (ypn > 0.99e30)     //The upper boundary condition is set either to be "natural"
		qn=un=0.0;				//or else to have a specified first derivative.
	else {					
		
		qn=0.5;
		un=(3.0/(x[n]-x[n-1]))*(ypn-(y[n]-y[n-1])/(x[n]-x[n-1]));
	}
	y2[n]=(un-qn*u[n-1])/(qn*y2[n-1]+1.0);
	for (k=n;k>=0;k--)		//This is the backsubstitution loop of the tridiagonal algorithm.
		y2[k]=y2[k]*y2[k+1]+u[k]; 
	
//	printf("here\n");
	
	free (u);
	//printf("here\n");
	
}
 
farmerdoug,

Given that the information and values as supplied are accurate I see no reason why either of the printf statements would fail to print.

Answer a few further questions.

What version of Mac OS are you developing this code on?

What version of Xcode is being used?

What is the file extension of the file that contains the 'spline' function?

What compiler is selected in the 'target' to compile this file?

What is the selected base OS?

Additionally is previous threads I believe you stated you're doing development using 'makefiles'. This implies you may not be using the Xcode IDE and thus may not have access to the Xcode GUI wrapped debugger. Is this true?
 
Snow Leopard,
the latest Xcode, I think, I'm not at work.
The spline function is from Numerical Recipes in C; everything is in main.c
I'm not sure what you mean by the target. Here is an example of a makefile, not the one for this code
Code:
CC = gcc
CFLAGS = -Wall  -g 
IDIR = /cfitsio/include
LIBS = -lm
CFITSIOLIB = /cfitsio/lib/libcfitsio.a
OBJS = matrix.o

clean:
		rm -f ${OBJS} ${EXECS}

EXECS	= 	getline2

OBJS	= 	getline2.o 

getline2:	getline2.c
		${CC} -DMAIN ${CFLAGS}  -I${IDIR}  p1640.h  getline2.c  ${CFITSIOLIB}  ${LIBS}  -o getline2

all:		${EXECS} ${OBJS}
 
bash-3.2$ gcc -v
Using built-in specs.
Target: i686-apple-darwin10
Configured with: /var/tmp/gcc/gcc-5646.1~2/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10
Thread model: posix
gcc version 4.2.1 (Apple Inc. build 5646) (dot 1)
bash-3.2$
 
The code compiles but I get a checksum error for freed pointer when I run.

Just a clue as to what's going on or how to debug this.
Thanks.

You debug this by testing it.

That means writing test programs that call the function being tested, and then do some checks to confirm it isn't overrunning anything or otherwise malfunctioning.

You should also write tests that confirm the function is doing its calculation correctly, for known-good inputs and outputs. That may be difficult for large data-sets, but you should be able to come up with smaller data-sets that define known inputs and outputs.

Example of a simple test program. I have no idea if the input data is meaningful or not. It's just to show some of the things you need to do when writing tests.

Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//#include <math.h>

void spline(const float x[], const float y[], int n, float yp1, float ypn, float y2[]);


// Any finite easily recognizable value unlikely to occur naturally.
static const float sentinel = -6.022141e23f;

static float*
floats( int count )
{
	// allocates count + 1 floats, puts sentinel in last position.
	float *floats = (float *) calloc( count + 1, sizeof(float) );
	if ( floats )
		floats[ count ] = sentinel;
	return floats;
}

static void
floatCheck( float* floats, int count, char *msg )
{
	if ( floats )
	{
		if ( floats[ count ] != sentinel )
			fprintf( stderr, "damaged %s\n", msg );
	}
}

static void
freeSafe( void * ptr )
{  if ( ptr ) free( ptr );  }

static float*
xlinear( int count )
{
	float *array = floats( count );
	if ( array )
	{
		int i;
		for ( i = 0;  i < count;  ++i )
		{  array[ i ] = (float) i;  }
	}
	return array;
}

static float*
xsquared( int count )
{
	float *array = floats( count );
	if ( array )
	{
		int i;
		for ( i = 0;  i < count;  ++i )
		{  array[ i ] = (float) i * i;  }  // i squared
	}
	return array;
}

int main (int argc, const char * argv[]) 
{
	const int N = 20;
	float * xx = xlinear( N );
	float * yy = xsquared( N );
	float * yy2 = floats( N );  // zeros

	if ( xx && yy && yy2 )
	{  
		spline( xx, yy, N, 20.0f, 30.0f, yy2 );  

		floatCheck( xx, N, "xx" );
		floatCheck( yy, N, "yy" );
		floatCheck( yy2, N, "yy2" );
	}
	else
		printf( "Something wasn't allocated.\n" );


	freeSafe( xx );
	freeSafe( yy );
	freeSafe( yy2 );

	return 0;
}

By the way, running this test program doesn't crash or malfunction, so my first guess is that you're doing something else wrong, probably in the unposted code that leads up to calling spline().

If you have more plausible sample data for inputs, I urge you to write a suitable test program and test your spline function yourself.


Your goal isn't just to write code, it's to demonstrate that the code you write works as expected.

I can tell you from experience that sometimes just the process of writing tests is enough to find bugs; running the test just confirms that the bug was fixed.

If writing tests seems like a waste of time, consider how much time you waste debugging faulty code by posting here and asking others to find your bugs. Not just your time, but lots of other people's, too. Personally, I may stop commenting on your posts, even when I know the answer, unless you provide at least a first attempt at a test program.

Unless something changes, nothing will change how you produce code. Realistically, this can't go on forever.
 
It's been tested. First of all, it was from Numerical Recipes in C which has been around for 100 years and through multiple editions. Second, this is not the first time, I've used it. I used it successfully last week in slightly differ code.

I don't write code; find it doesn't work; and post it. I don't usually write test code but I do test my code if it doesn't work. What I do do is fill the code with print statements and comment out parts until I've located the problem and then try to make some sense out of it.

In this case, as you can see there seems to be a problem in calloc as it returns no error but the code doesn't get through it. When I comment the spline call out of the main program, I don't have any problems.

If you don't want to reply to my posts that's obviously your prerogative but I didn't ask anybody to debug my code only to provide some suggestions on how I might do it, which you did. Thank you. If you want to debug it, I'll be glad to post the whole code and a data set.
 
In this case, as you can see there seems to be a problem in calloc as it returns no error but the code doesn't get through it. When I comment the spline call out of the main program, I don't have any problems.

I don't know what you mean by "the code doesn't get through it". When I run my test program, it gets through the calloc() in spline() just fine, and successfully returns. Even when I change my value of N from 20 to 175, or 400, or 1000.

You can confirm that spline() returns successfully by adding a printf("Done\n") right before the return in main(). The code is copy-and-pasteable into a .c file. I included everything except the spline function, which I literally copied and pasted from your post, with no changes whatsoever.

I've already posted simple code that demonstrates there isn't a problem in spline().

And your own earlier use of spline() also suggests you have code that demonstrates there isn't a problem in spline().

As a hypothesis, suppose that spline() is working correctly, as demonstrated by my posted test program, and your own earlier use. What then might be the cause of a problem in your program?

The simplest logically consistent explanation that fits the available facts is "something in your program that occurs before spline() is called, is causing a problem in spline()". Yet you haven't posted any of that code.

Post your code that demonstrates the problem, as at least a minimal self-contained compilable example.
 
The code is at work but I will have to write additional code unless you can use the cfitsio library.
What I mean by the code doesn't get through it refers to my first post.I don't get a error from the calloc nor does the print statement after print.
 
What I do do is fill the code with print statements and comment out parts until I've located the problem and then try to make some sense out of it.

That's your first mistake. Learn to use a debugger. You will be a lot more productive that way. Plus, there are certain types of bugs that are virtually impossible to find simply by littering your code with printfs.

In this case, as you can see there seems to be a problem in calloc as it returns no error but the code doesn't get through it. When I comment the spline call out of the main program, I don't have any problems.

I highly doubt that there is a bug in calloc. Likewise, there is probably nothing wrong with that few lines of code you originally posted (that call calloc). As mentioned above, it is probably something outside of spline. Maybe you're passing in invalid parameters and this causes spline to possibly overrun arrays (e.g. that first for loop could overrun x[] and y[] if you didn't make them big enough when you called spline). The error you are getting, to me, sounds something like you are trying to use memory that calloc previously allocated and after you freed it but I'm not sure. Is calloc/malloc being used in other parts of your code? Maybe there are bugs there and the calloc call in spline is simply letting you know about it. Again, maybe because you've got a rogue pointer somewhere, overrunning an array, using something that is uninitialized? Use a debugger and step through your code. Check any pointers you are using, see if you are attempting to use an array outside its bounds, check your stack and see if it looks okay, see if you are attempting to use allocated memory after you call free, etc.
 
I used a debugger years ago when programming in Microsoft C. I've been a little reluctant start with new things; I have enough problems to solve but maybe the time has come. I suspect that your diagnostics of the problem is correct but isn't calloc supposed to protect you from overwriting memory?

Thanks.

In "The Searchers", when they learn that the farmer house has been attacked Tab Hunter takes off on his horse; John Wayne rests his. Wayne gets there first. Too bad I always think I can solve something the easy way.
 
I used a debugger years ago when programming in Microsoft C. I've been a little reluctant start with new things; I have enough problems to solve but maybe the time has come. I suspect that your diagnostics of the problem is correct but isn't calloc supposed to protect you from overwriting memory?

Suck it up and take the time to learn how to use a debugger. They are very powerful tools and something that every programmer should know how to use. Yes, it will probably be a pain in the butt at first, but it will pay off in the long run. Fight the urge to add printfs all over the place. You've got lots of options here as for what debugger to use. XCode is an obvious one. There are also a few front-ends to gdb out there that are easy to use, like ddd and insight (never used either one on a Mac but they would probably work). You can also just use gdb from the command line (that's what I do). Doing the latter can be very intimidating at first but I actually prefer it to using something with a GUI.

As for calloc, well, all bets are off if you've got some rogue pointer destroying memory all over the place or if you're over-writing arrays. It's not going to protect you from over-writing memory. It just gives you a pointer to a spot in memory. You could be doing all kinds of crazy things with that pointer, even after you call 'free'. I'm just guessing though. If you can give us a (small) complete example that exploits your problem, then we can be of more help. Until then, all I can say is 'hook up a debugger!'
 
I use gdb but I don't understand all that it tells me. The problem with sucking it up , is that I'm not a programmer as I've said. I may finish with this code and not have to write any code for months and when I do, it may be in a different language. When things get really bad, I may have to program in 3 or four languages at once. It gets confusing.
 
I would modify 'spline' to exit if 'calloc' returns NULL.

Code:
   if ( !( u = (float *)calloc (2*n,sizeof (float)) ))
    {
        printf( "calloc failed\n");
        exit(EXIT_FAILURE);
    }
I think it likely you're passing in bad data.

I would also check for values of 'n' < 2 as 'calloc' will gladly return a pointer when requested to allocate zero bytes of memory at which point ANY writes to array 'u' will wreak havoc down the road.

Read the man page on 'calloc' especially the section 'DEBUGGING ALLOCATION ERRORS'.
 
I'm coming into this party late. From what I gather, you aren't getting particularly far with gdb itself.

From your initial post, the error itself implies to me that the *bug* is somewhere else completely. "The code compiles but I get a checksum error for freed pointer when I run." That says to me that the memory management system is *finding* the problem when calloc is called--this doesn't mean the call to calloc itself is faulty or even remotely related to the bug.

Check the malloc man page. Here are a few environment variables you should set:

MallocGuardEdges
MallocScribble
MallocCheckHeapStart <s>


Also, you don't have to use Xcode to build an executable in order to use Xcode to debug it. I don't recall all of the details, but there's a way to add a "custom executable" to a project, and so long as the debug symbols are available, Xcode should be able to debug your program.
 
Detrius, mslide The other reason I don't use the Xcode debugger is that I can't get my cfitsio library to link in XCode. I talked to NASA about it again and Lloyd is trying to help.
 
progress. After a night's sleep; ignoring this until noon, and your words in my head. I got past the problem. I commented out all the allocated memory that I wouldn't need until after the first call to spline. That fixed that and lead to me finding a few errors of omission which should help later on. At the moment I have to go back and find out why my magnified images are empty. I should be able to do that.

Thanks again.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.