Deleting Structures

Discussion in 'Mac Programming' started by bobber205, Apr 20, 2007.

  1. bobber205 macrumors 68020

    bobber205

    Joined:
    Nov 15, 2005
    Location:
    Oregon
    #1
    Got a couple questions. (this applies to C++)

    I have a structure like this:

    Code:
    struct Word 
    {
    	int count;
        char* actualself;
    };
    
    I am dynamically creating a array of Word pointers. That's the easier part.

    Now that I'm done,I'm trying to minimize my memory leaks. Like a good coder does. :D

    But now I'm like *arg* Kidding aside, I would like your guys advice on how to delete structures and dynamically allocated memory that those structures hold.

    Here's what I've tried thus far:

    Code:
    for (int i = 0; i < wordcount; i++) {
    	cout << "I " << i << endl;
    delete [] wordarray[i].actualself;
    }
    delete [] wordarray;
    
    Assume that the loop does not go out of bounds. (it doesn't I can assure it. It craps out on the first time it tried to delete.)

    When it reaches the first delete in the for loop, I get a HEAP CORRUPTION DETECTED error in VS.

    If I comment out the for loop and just do the last delete statement, it runs fine, but I still have lots and lots of memory leaks. This is essentially the only allocated memory that I do runtime. I just tried taking out all deletes and leaving the last one in: it results into 10 memory leaks each time.

    What's up?
     
  2. mags631 Guest

    Joined:
    Mar 6, 2007
    #2
    How are you allocating actualself? With new char[..]?
     
  3. bobber205 thread starter macrumors 68020

    bobber205

    Joined:
    Nov 15, 2005
    Location:
    Oregon
    #3
    Yes.

    It looks like this:

    Code:
    
    Words[i].actualself = new char[strlen(wordtoadd)];
    
    
     
  4. bbarnhart macrumors 6502a

    bbarnhart

    Joined:
    Jan 16, 2002
    Location:
    Stilwell, Kansas
    #4
    Code:
    #include <iostream>
    
    int main (int argc, char * const argv[]) {
        // insert code here...
        std::cout << "Hello, World!\n";
        
        struct my_struct
        {
          int my_int;
          char* my_string;
        };
        
        my_struct* my_struct_ptr = new my_struct[10];
       
        int i;
         
        for (i=0; i < 10; i++)
        {
          my_struct_ptr[i].my_string = new char[50];
        }
        
        for (i=0; i < 10; i++)
        {
          delete [] my_struct_ptr[i].my_string;
        }
        
        delete [] my_struct_ptr;
        
        return 0;
    }
    The above code does something similar. Look through it and see if you can find your mistake.
     
  5. ElectricSheep macrumors 6502

    ElectricSheep

    Joined:
    Feb 18, 2004
    Location:
    Wilmington, DE
    #5
    Do you have any code to ensure that new is returning a valid pointer? Its a bad idea to just blindly accept anything that new gives back. Always ensure that you have valid pointers.
     
  6. bobber205 thread starter macrumors 68020

    bobber205

    Joined:
    Nov 15, 2005
    Location:
    Oregon
    #6
    Yes. I have valid pointers being returned. :D

    I am able to use the same loop to print out my structures.
     
  7. dcr macrumors member

    Joined:
    Jun 10, 2002
    #7
    contrary to popular belief, in standard C++ operator new does not return invalid pointers. if it's going to fail (say with out of memory) it will instead throw an exception like std::bad_alloc and bring your newbie program down in flames. :)

    http://en.wikipedia.org/wiki/New_(c++)
     
  8. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #8
    How many bytes does it take to store a string like "Hello" ? Five or six?
     
  9. gnasher729 macrumors P6

    gnasher729

    Joined:
    Nov 25, 2005
    #9
    Where's the constructor and destructor for struct Word? You know, the constructor that initializes "actualself" to NULL, and the destructor that deallocates it.
     
  10. lazydog macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #10
    I think this errror message is saying that delete[] has detected that you have overflowed the character array when you used it at some point. So, the bug lies elsewhere in your program… probably where gnasher729 was hinting, ie you've not allocated enough bytes to hold a string that you've written to actualself.

    I would also agree with gnasher729 about using constructors and destructors, also I would add a method for setting the string, ie something like this:-

    Code:
    struct Word 
    {
          Word() : actualself( 0L ) {}
          ~Word() { delete[] actualself ; }
         
          void set_actualself( const char* str ) { actualself = new[ strlen( str ) + 1 ] ; }
    
    	int count;
        char* actualself;
    
    };
    hope this helps

    b e n
     
  11. mags631 Guest

    Joined:
    Mar 6, 2007
    #11
    That would do it...
     
  12. bobber205 thread starter macrumors 68020

    bobber205

    Joined:
    Nov 15, 2005
    Location:
    Oregon
  13. bbarnhart macrumors 6502a

    bbarnhart

    Joined:
    Jan 16, 2002
    Location:
    Stilwell, Kansas
    #13
    Sets actualself to zero which is also NULL. The L in 0L means to tell the compiler that the zero is a long(?) and not some other type (int, short, byte, char...). This is to assure that zero is a full 32-bit zero.
     
  14. bobber205 thread starter macrumors 68020

    bobber205

    Joined:
    Nov 15, 2005
    Location:
    Oregon
    #14
    So I assume deleting with delete a word structure would trigger the deconstructor?
     
  15. mags631 Guest

    Joined:
    Mar 6, 2007
    #15
    delete pointer - calls the destructor and then deallocates the memory
    delete [] pointer - calls the destructor for each member of the array and then deallocates the memory of the array.
     
  16. lazydog macrumors 6502a

    Joined:
    Sep 3, 2005
    Location:
    Cramlington, UK
    #16
    Ooops, assuming set_actualself() can be called more than once it has a memory leak! It should be like this:-

    Code:
    void set_actualself( const char* str )
    {
       delete[] actualself ;
       actualself = new[ strlen( str ) + 1 ] ;
    }
    
    By the way in C++ it's okay to call delete and delete[] on a null pointer. Since the constructor initialises actualself with null, calling delete[] actualself is fine before setting actualself.

    b e n
     

Share This Page