Thread: How to not cast this malloc/realloc

  1. #1
    Registered User
    Join Date
    Sep 2007
    Posts
    131

    How to not cast this malloc/realloc

    I keep seeing people say we should not be casting mallocs and its family of functions, but I'm having trouble getting this to work without a cast:

    Code:
    	if( geo->num_triangles > geo->tlist_capacity )
    	{
    		// Double the list size
    		if(( new_tlist = (Triangle **)realloc( geo->tlist, geo->num_triangles * 2 * sizeof( Triangle * ))) == NULL )
    		{
    			disp_error( "Error allocating memory for vlist\n", __FILE__, __LINE__ );
    			geo->num_triangles--;
    			return false;
    		}
    		geo->tlist = new_tlist;
    		geo->tlist_capacity = geo->num_triangles * 2;
    
    	}
    And similarly (from the same function):

    Code:
    	// Allocate for the new triangle
    	if(( new_triangle = (Triangle *)malloc(sizeof(Triangle))) == NULL )
    	{
    		disp_error( "Error allocating for new triangle\n", __FILE__, __LINE__ );
    		return false;
    	}
    How would I allocate for structures or arrays of structures without a cast? I'm getting mismatch errors without a cast.

  2. #2
    Registered User
    Join Date
    Dec 2011
    Posts
    795
    What compiler are you using? Unless you post this, we can't give specific help

    But in general, you're trying to compile as C++ instead of C, so turn this off.

  3. #3
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    I'm using VC++ Express 2010

  4. #4
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    In C++ you need the cast, but you don't need it in C. So you are probably compiling your program as C++. Change the filename extension to .c instead of .cpp or whatever.

    The whole not casting malloc/realloc thing is stylistic and some people might disagree. See the C-FAQ entry on this (check out the next two entries also).

    EDIT: Also, you should ensure that your included stdlib.h.
    Last edited by oogabooga; 03-14-2012 at 07:11 PM.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  5. #5
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    ok, thanks guys, but I kind of like some of C++'s conventions (operator overloading, not having to specify the struct keyword, etc).

    I may stay with what I have. I may also switch to pure C later, after the project is finished. This is basically a rewrite of a C++ version I made last month. It took me a month of casual coding to get that project done, so I figure this will take no more than a week since I have a code base and working algorithms to copy.
    Last edited by Cynic; 03-14-2012 at 07:33 PM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Cynic
    ok, thanks guys, but I kind of like some of C++'s conventions (operator overloading, not having to specify the struct keyword, etc).
    Then use C++? (Though "not having to specify the struct keyword" can be mitigated by typedef.)
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Quote Originally Posted by laserlight View Post
    Then use C++? (Though "not having to specify the struct keyword" can be mitigated by typedef.)
    I did for this first part of the project, the volume spanner, but I found encapsulation to be more a hindrance than a help. Plus seeing how fat the exe gets and how my machine was hammered after processing a 3D object kind of put me off. I'm undecided, but just doing some computational geometry for fun and build up to the game I have planned.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Cynic
    I found encapsulation to be more a hindrance than a help.
    How so?

    Quote Originally Posted by Cynic
    how fat the exe gets
    This may be overhead from statically linking to unnecessary libraries, but in any case is this really a problem for you?

    Quote Originally Posted by Cynic
    how my machine was hammered after processing a 3D object
    Switching to C won't change this.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    Data hiding and accessibility was a pita and forced several minor rewrites. I don't find it that valuable since I don't access structured data unless I need to. Sometimes, trying to decide which object should handle what particular function was annoying as it meant I was having to getData() from one object or another to be able to use it.

    Switching to C won't change this.
    Maybe, maybe not. I don't know. The project didn't allocate a huge pool of memory(a vector of vertices and a vector of triangles where each vertex of a triangle was really a pointer reference to the memory block of the vertex in the preceding vector of vertices) and instead worked one span or line at a time until the end when I had to read and write a file to prepend info. After it was over, I had to wait 10 mins or so for the system to recover. My program didn't allocate that much memory, but was bogging down my whole machine and the exe is only 43K. The worst offender was a 1x1x1 rotated cube: 8 vertices, 16 triangles. Maybe it's windows and I should try to get a linux box running again and use that. Don't know.

    I don't know, right now, I'm just blowing time and playing with comp geom and calculating volumes of 3D objects and generating physical data from it. Right now, I think the biggest hurdle is floating point and trying to get as accurate as possible.
    Last edited by Cynic; 03-14-2012 at 08:42 PM.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Cynic
    Data hiding and accessibility was a pita and forced several minor rewrites. I don't find it that valuable since I don't access structured data unless I need to. Sometimes, trying to decide which object should handle what particular function was annoying as it meant I was having to getData() from one object or another to be able to use it.
    Hmm...
    • The use of encapsulation and access control in C++ is optional. If you find that your data is better suited as an aggregate than encapsulated in a class, then go ahead and make it so.
    • "Data hiding" is a concept that is not restricted to C++. In fact, private access in C++ is not quite "data hiding". THe use of the pimpl idiom, also known as opaque pointer, is more like "data hiding", and in fact is a commonly used idiom in C especially for libraries.
    • The concern of "getData() from one object or another" sounds like you just did not provide a suitable interface for your classes. This problem would persist in C if you don't learn how to design your abstractions.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    Registered User
    Join Date
    Sep 2007
    Posts
    131
    The concern of "getData() from one object or another" sounds like you just did not provide a suitable interface for your classes. This problem would persist in C if you don't learn how to design your abstractions.
    You're more than likely right. I struggle with C++ and I find my dev times are increased ten fold trying to work with it and learn it. I never did transition well back in the 90s, but I also still don't need to be struggling to learn a new language's nuances. C++ is a seriously different beast at the higher level.

  12. #12
    Registered User ledow's Avatar
    Join Date
    Dec 2011
    Posts
    435
    If you have a broken compiler setup, casting malloc can hide some errors (but will almost certainly break the program enough that you have a problem anyway).

    If you are sloppy when changing types of an established variable (i.e. not searching for instances of it, and castings to it), casting malloc can cause you to mis-cast between the old and new (but will almost certainly break the program enough that you have a problem anyway).

    The cast is not, strictly, necessary. That said, even people who are absolutely anal in their programming - like Simon Tatham (of PuTTY fame) and others - use these sorts of casts all the time, even inside automated macros (I'm a big fan of his "snew", "snewn" etc. macros, simple as they may be:

    Code:
    #define snew(type) \
        ( (type *) smalloc (sizeof (type)) )
    #define snewn(number, type) \
        ( (type *) smalloc ((number) * sizeof (type)) )
    - snew(char) will allocate space for a char and return you a char *. snewn(20, Structure) will allocate enough size for 20 of your structure and return Structure * to them). It's only a problem if you think you're going to forget that you cast malloc.

    Personally, I *always* cast malloc (unless I'm intending to store its return in a void* anyway). It helps me find more problems than it causes (can't say I've ever really had the problems described in that FAQ, for example). malloc is one of those functions that you have to be careful enough around anyway - you have to check sizes, the size of the types you are handling, the number of them, etc. before you can write a malloc statement. And going back and fiddling with stuff later is a sure-fire way to break a working malloc because you *will* miss something if you don't search for every instance of the type Compared to the mistakes possible there, a mis-casting is a really minor thing that often causes quite obvious compiler errors anyway, and I find the "lacking stdlib.h" excuse really quite weak.

    - Compiler warnings are like "Bridge Out Ahead" warnings. DON'T just ignore them.
    - A compiler error is something SO stupid that the compiler genuinely can't carry on with its job. A compiler warning is the compiler saying "Well, that's bloody stupid but if you WANT to ignore me..." and carrying on.
    - The best debugging tool in the world is a bunch of printf()'s for everything important around the bits you think might be wrong.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by ledow
    - snew(char) will allocate space for a char and return you a char *. snewn(20, Structure) will allocate enough size for 20 of your structure and return Structure * to them).
    This probably explains why you say that casting "helps me find more problems than it causes": since you are specifying the type rather than taking advantage of sizeof(*p) resulting in the correct type for the destination pointer p, there is the worry that should the type of p change, the type specified would be a mismatch. A cast would then allow the compiler to warn of such a mismatch.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. malloc and realloc
    By jayfriend in forum C Programming
    Replies: 4
    Last Post: 01-05-2007, 02:25 PM
  2. malloc and realloc
    By odysseus.lost in forum C Programming
    Replies: 3
    Last Post: 05-27-2005, 08:44 AM
  3. Need help on malloc and realloc
    By YevGenius in forum C Programming
    Replies: 8
    Last Post: 03-06-2004, 01:55 AM
  4. malloc and realloc
    By C-Struggler in forum C Programming
    Replies: 2
    Last Post: 03-11-2003, 11:31 AM
  5. cast malloc() WHY?.
    By Unregistered in forum C Programming
    Replies: 3
    Last Post: 01-28-2002, 06:04 PM