[RESOLVED] Validity of new/delete pair (or malloc/free) after pointer casting
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: [RESOLVED] Validity of new/delete pair (or malloc/free) after pointer casting

  1. #1
    Join Date
    Feb 2011
    Location
    United States
    Posts
    1,006

    [RESOLVED] Validity of new/delete pair (or malloc/free) after pointer casting

    Pretty much a simple question, but I wanted to confirm what I think I understood from reading elsewhere:

    Goal: To allocate some memory as a char*, read in some binary data, re-interpret it as a float* and then free the memory.

    My code looks like:

    Code:
    void someFunction(float* &result)
    {
        char * tmp = new char[1000];
    
        //...Fill the char buffer here...
    
        result = (float*)tmp; //Reinterpret binary data as floats
    }
    
    main(void)
    {
        float  * floatData;
        someFunction(floatData);
    
        //Do something
    
        delete[] (char*)floatData;  //Release the memory
    }
    Is the cast back to char* necessary on the red line (or could I have validly left it as float*)? Would it be different if I had written char * tmp = (char*)malloc(sizeof(char)*1000); on the blue line (and correspondingly used free (char*)floatData on the red line?

    Thanks for any guidance you might have.
    Last edited by BioPhysEngr; December 22nd, 2012 at 12:50 AM. Reason: Ah, my original code will segfault. Corrected syntax to pass the result pointer by referece.
    Best Regards,

    BioPhysEngr
    http://blog.biophysengr.net
    --
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  2. #2
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,286

    Re: Validity of new/delete pair (or malloc/free) after pointer casting

    Personally, I would use new float[N] instead, then re-interpret the float* as unsigned char* to fill with binary data, then just delete[] the float* (say via smart pointer).
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  3. #3
    Join Date
    Apr 1999
    Posts
    27,427

    Re: Validity of new/delete pair (or malloc/free) after pointer casting

    Quote Originally Posted by BioPhysEngr View Post
    Pretty much a simple question, but I wanted to confirm what I think I understood from reading elsewhere:

    Goal: To allocate some memory as a char*, read in some binary data, re-interpret it as a float* and then free the memory.
    Why not just declare the data as char from the beginning, do whatever you want with it, and then delete it? Then you need no casting. Or do the opposite -- declare a float*, allocate as a float*, and delete. No casting needed.

    Also, what if there is an issue at the end of the buffer? For example can you guarantee that 1000/sizeof(float) is evenly divisible? That last float at the end would tread on unallocated memory.

    But I feel that the behaviour is technically undefined. Casting the delete to some other type is asking for trouble in the long run. The thing saving you is that the types are simple types (char, float), but if it were a non-POD type, this wouldn't work out too well. Also, if for some reason array delete is overloaded, then all bets are off, even with simple types.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; December 22nd, 2012 at 01:08 AM.

  4. #4
    Join Date
    Feb 2011
    Location
    United States
    Posts
    1,006

    Re: Validity of new/delete pair (or malloc/free) after pointer casting

    I see; thanks very much for your input. So, if I were reading data from a file using an ifstream (which requires a char* to fill with data) in someFunction(...), it would be better to do:

    Code:
    void someFunction(float* &result)
    {
        //Assume some open ifstream called "in" and a known integer, fileSize
        int numFloats = fileSize / sizeof(float);
        result = new float[numFloats];
        in.read((char*)result, numFloats * sizeof(float));
    }
    Thereby avoiding the cast after allocation entirely, per laserlight. Then, I can just call delete[] floatData in the main subroutine to avoid any potentially undefined behavior?

    Understood correctly?
    Best Regards,

    BioPhysEngr
    http://blog.biophysengr.net
    --
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  5. #5
    Join Date
    Jan 2006
    Location
    Singapore
    Posts
    6,286

    Re: Validity of new/delete pair (or malloc/free) after pointer casting

    Yes, that should be fine. Of course, you could use a std::vector<float> instead, then write:
    Code:
    in.read(&result[0], result.size() * sizeof(result[0]));
    with the parameter of someFunction changed accordingly.
    C + C++ Compiler: MinGW port of GCC
    Build + Version Control System: SCons + Bazaar

    Look up a C/C++ Reference and learn How To Ask Questions The Smart Way
    Kindly rate my posts if you found them useful

  6. #6
    Join Date
    Feb 2011
    Location
    United States
    Posts
    1,006

    Re: Validity of new/delete pair (or malloc/free) after pointer casting

    Great; thanks for your help!
    Best Regards,

    BioPhysEngr
    http://blog.biophysengr.net
    --
    All advice is offered in good faith only. You are ultimately responsible for effects of your programs and the integrity of the machines they run on.

  7. #7
    Join Date
    May 2009
    Posts
    2,413

    Re: [RESOLVED] Validity of new/delete pair (or malloc/free) after pointer casting

    Quote Originally Posted by BioPhysEngr View Post
    Is the cast back to char* necessary on the red line
    I would be surprised if it was. The delete[] operator takes a void* parameter so regardless of whether you pass a char* or a float* that type information is lost in the call anyway.

    But although correct this type of casting isn't directly elegant. I would separate the external and internal representation of the numbers. On file I would use a text format and then convert to and from the internal binary format. Boost has a conversion library called lexical_cast one can use for this.

  8. #8
    Join Date
    May 2009
    Posts
    2,413

    Re: Validity of new/delete pair (or malloc/free) after pointer casting

    Quote Originally Posted by Paul McKenzie View Post
    Casting the delete to some other type is asking for trouble in the long run.
    Formally it shouldn't be a problem because any pointer passed to delete[] is cast to void* (so it doesn't matter what type they are).

  9. #9
    Join Date
    Aug 2002
    Location
    Madrid
    Posts
    4,588

    Re: [RESOLVED] Validity of new/delete pair (or malloc/free) after pointer casting

    That's not entirely correct. When you use delete [], the destructors for each individual object are called first. If you replace char and float by car and bike classes, it's obvious that using the wrong type when calling delete [] is asking for trouble. Because intrinsic types don't have destructors, this is not really a problem here, but it could be in the future if the types are changed to something else, and you're not aware that of the difference in types in new [] and delete [].
    Get this small utility to do basic syntax highlighting in vBulletin forums (like Codeguru) easily.
    Supports C++ and VB out of the box, but can be configured for other languages.

  10. #10
    Join Date
    Oct 2008
    Posts
    1,135

    Re: [RESOLVED] Validity of new/delete pair (or malloc/free) after pointer casting

    probably nuzzle is confusing a delete expression with a call to operator delete. In the former case no cast is performed for pointer types ( conversion operators to pointer will be invoked for non pointer types though; BTW, invoking delete on a void* is an error in c++11 because now pointer operands are requried to be pointers to object type; in c++2003 it was just UB ).

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center