Thread: Memory handling functions (newbie questions)

  1. #1
    Registered User
    Join Date
    Mar 2009
    Posts
    46

    Memory handling functions (newbie questions)

    OK I'm pretty much a C programming newbie (or to be more accurate and 'oldbie' who has forgotten nearly all he ever knew) and I'm trying to get the handle on some subtle differences between two sets of code that do the same (or similar) thing.

    This is a macro from Program A
    Code:
    /* Wipe an array of type T[N], at location P, and return P */	
    #define C_WIPE(P, N, T) \	
    	(memset((P), 0, (N) * sizeof(T)))
    And this is an example of it in use
    Code:
            /* Clear the "aux" array */
            (void)C_WIPE(aux, MAX_DEPTH, s16b);
    Now the same area from the (distant relation) Program B
    Code:
    /* Wipe an array of type T[N], at location P, and return P */				
    #define C_WIPE(P,N,T) \				
    	(T*)(memset((char*)(P),0,(N) * sizeof(T)))
    and it in use
    Code:
    	/* Clear the "aux" array */
    	C_WIPE(&aux, MAX_DEPTH, s16b);
    The code in Program B was probably previously used in Program A before being updated, so I might assume that A is more 'correct', but it is not clear to me why (if so).

    Some things that I did think
    & (address of) and * (pointer to)
    look like they'd cancel each other out so I'm not sure why version B goes round the houses like it seems to do. Unless it's to turn it into a pointer to char type in particular.

    B takes the trouble to return it as 'pointer to type T' but in practice the return value is not looked at in any code used in the program (sometimes it is cast to (void), sometimes not).

    Any comments?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by PaulBlay
    Some things that I did think
    & (address of) and * (pointer to)
    look like they'd cancel each other out so I'm not sure why version B goes round the houses like it seems to do. Unless it's to turn it into a pointer to char type in particular.
    Yes, you are looking at a cast to char*, but such a cast is unnecessary since the first parameter of memset() is a void*, and T* is implicitly convertible to void*, where T is some object type.

    Quote Originally Posted by PaulBlay
    B takes the trouble to return it as 'pointer to type T' but in practice the return value is not looked at in any code used in the program (sometimes it is cast to (void), sometimes not).
    It might be an attempt to silence a static analysis tool from giving a false alert (especially true for a cast to void), but other than that it is unnecessary since memset() returns a void*, and in C, void* is implicitly convertible to T*, where T is some object type.
    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

  3. #3
    Registered User
    Join Date
    Mar 2009
    Posts
    46
    Thank you for that clear explanation.

    There are some things in a later part of the same bit of the program that are confusing me but I think I will have to struggle with them myself for a bit longer. At least till I can work out what questions I need to ask. ;-)

  4. #4
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    You are right: in practice the memset's return value is rarely looked at. I don't think I've ever needed it - as I already have the pointer. The return value has no mechanism to indicate an error condition (NULL value for example). In an on-line documentation I found:

    The memset() function returns s; no return value is reserved to indicate an error.

  5. #5
    Registered User
    Join Date
    Mar 2009
    Posts
    46
    Here's another question, not directly related but from the same pair of programs.
    My question is about vptr (used in replacement for void *) is it necessary?

    Program A
    Code:
    /* De-allocate memory */
    void *mem_free(void *p);
    (mem_free more or less just points to free)

    Program B
    Code:
    /* A standard pointer (to "void" because ANSI C says so) */
    typedef void *vptr;
    Code:
    /* De-allocate a given amount of memory */
    extern vptr rnfree(vptr p, huge len);
    (rnfree is much the same, but 'len' seems to be used in an attempt to track memory leaks)

    Code:
     /* Note that, for some reason, some allocation macros may disallow
     * "stars" in type names, but you can use typedefs to circumvent 
     * this.  For example, instead of "type **p; MAKE(p,type*);" you
     * can use "typedef type *type_ptr; type_ptr *p; MAKE(p,type_ptr)".
     */
    Apart from 'because ANSI C says so' that appears to be the only relevant explanation I can find in the code. Is it likely that replacing the vptr's all over the code with void * will have any adverse affect?

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,412
    Quote Originally Posted by PaulBlay
    My question is about vptr (used in replacement for void *) is it necessary?
    No.

    Quote Originally Posted by PaulBlay
    Is it likely that replacing the vptr's all over the code with void * will have any adverse affect?
    Maybe, if that comment about macros is true and applies in your case. A direct text replacement may or may not work, e.g., const vptr is void* const, not const void*.
    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
    Mar 2009
    Posts
    46
    Quote Originally Posted by laserlight View Post
    Maybe, if that comment about macros is true and applies in your case. A direct text replacement may or may not work, e.g., const vptr is void* const, not const void*.
    The code isn't very 'const correct' so I don't think I'll have to worry about that problem (at least any more than I already did ;-).

    The two programs are distributed as source code to roughly the same 'market' ( = target audience) so if Program A doesn't have any problems I don't expect Program B to. I was just hoping for a little more certainty.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. C++ memory questions
    By jcafaro10 in forum C++ Programming
    Replies: 2
    Last Post: 04-05-2009, 09:24 PM
  2. tools for finding memory leaks
    By stanlvw in forum C++ Programming
    Replies: 4
    Last Post: 04-03-2009, 11:41 AM
  3. Problems with shared memory shmdt() shmctl()
    By Jcarroll in forum C Programming
    Replies: 1
    Last Post: 03-17-2009, 10:48 PM
  4. Real newbie with VC6 questions
    By MagiZedd in forum Windows Programming
    Replies: 8
    Last Post: 10-15-2001, 08:27 PM
  5. memory allocation newbie problem
    By larry in forum C++ Programming
    Replies: 11
    Last Post: 10-08-2001, 08:58 AM