Just give me a clue.

Discussion in 'Mac Programming' started by farmerdoug, Feb 17, 2010.

  1. farmerdoug macrumors 6502a

    Joined:
    Sep 16, 2008
    #1
    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.
     
  2. Cromulent macrumors 603

    Cromulent

    Joined:
    Oct 2, 2006
    Location:
    The Land of Hope and Glory
    #2
    Set a breakpoint and step through your code.
     
  3. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #3
    What exactly am I looking for? It looks like I've confined the error to a single line?
    thanks
     
  4. milbournosphere macrumors 6502a

    milbournosphere

    Joined:
    Mar 3, 2009
    Location:
    San Diego, CA
    #4
    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
     
  5. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #5
    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");
    	
    }
    
     
  6. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #6
    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?
     
  7. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #7
    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}
    
    
    
     
  8. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
  9. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #9
    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$
     
  10. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #10
    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.
     
  11. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #11
    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.
     
  12. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #12
    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.
     
  13. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #13
    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.
     
  14. mslide macrumors 6502a

    Joined:
    Sep 17, 2007
    #14
    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.

    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.
     
  15. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #15
    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.
     
  16. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #16
    No way.

    Why would you think that?
     
  17. mslide macrumors 6502a

    Joined:
    Sep 17, 2007
    #17
    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!'
     
  18. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #18
    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.
     
  19. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #19
    Hint: Is "n" ever zero? I can't imagine that calloc would enjoy a zero being passed as its first parameter.
     
  20. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
  21. lloyddean macrumors 6502a

    Joined:
    May 10, 2009
    Location:
    Des Moines, WA
    #21
    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'.
     
  22. Detrius macrumors 68000

    Joined:
    Sep 10, 2008
    Location:
    Asheville, NC
    #22
    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.
     
  23. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #23
    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.
     
  24. farmerdoug thread starter macrumors 6502a

    Joined:
    Sep 16, 2008
    #24
    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.
     

Share This Page