0

I am very beginner in c++ and trying to understand pointers, arrays and dynamic allocations. And in this code I am trying to allocate and then deallocate a 2d string array but the code doesn't work. The part delete[] contents[i] doesn't do the job that I want it to do. I did the same thing for 2d integer array and it worked. So I am really confused.

#include <iostream>
using namespace std;

int main() {
    // Write C++ code here
    string** contents = new string* [2]; //contents going to be 2(rows)x3(column) 2D string Array
    string* sptr; // to test the memory leak
    
    for(int i = 0; i < 2; i++) {
        //contents[i] is an array of pointers which the every element are pointing 
        //to string arrays with the size of 3
        contents[i] = new string[3];
    }
    
    contents [1] [1] = "safe";
    sptr = contents[1]; 
    cout << "sptr[1]: " << sptr[1] <<endl;
    cout << "contents[1][1]: " << contents[1][1] <<endl;

    
    for(int i = 0; i < 2; i++) {
        //Problemetic PART !!!
        //deleting the string arrays with size 3 (actually not working but I didn't understand why.)
        delete[] contents[i];
    }
    
    cout<<"--After delete[] contents[i] for each i {0,1};"<<endl;
    cout << "sptr[1]: " << sptr[1]  <<endl; //nothing changed
    cout << "contents[1][1]: " << contents[1][1] <<endl; //nothing changed
    
    contents[1][1] = "dang";
    
    cout<<"--contents[1][1] is changed to dang"<<endl;
    cout << "sptr[1]: " << sptr[1]  <<endl;
    
    //I can delete the pointers in the pointer array but I just lose the adresses of the strings 
    //arrays and they still remain to be exist in the memory. (Memory Leak)
    delete[] contents;
    
    cout<<"--After delete[] contents;"<<endl;
    cout << "contents[1][1]: " << contents[1][1] <<endl;//since I lost the pointer I can't 
                                                        //have acces to the string with using
                                                        //the contents
                                                        
    cout << "sptr[1]: " << sptr[1]  <<endl; //but I still have the string in memory
    
    
    return 0;
}
output is :
sptr[1]: safe
contents[1][1]: safe
--After delete[] contents[i] for each i {0,1};
sptr[1]: safe
contents[1][1]: safe
--contents[1][1] is changed to dang
sptr[1]: dang
--After delete[] contents;
contents[1][1]: 
sptr[1]: dang
uk628
  • 1
  • Thank god for the `// Write C++ code here` or I would never have been able to figure out that this was code. – user4581301 Nov 04 '21 at 19:02
  • [Look at this code if you must do things this way](https://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in-c/21944048#21944048). Replace `double` with `std::string`. As to your claim that this worked with `int`, I bet it didn't really work. There should have been absolutely no changes to the code, except for changing `int` to `std::string` if you are claiming that the `int` version worked. The `std::string` version probably exposed the hidden bug(s) in your integer version. – PaulMcKenzie Nov 04 '21 at 19:04
  • 1
    You are trying to access objects after you `delete` them. This is undefined behaviour. Everything after the second `for` loop is an error. Use [the address sanitizer](https://godbolt.org/z/qT9osYo7j) to catch such errors. – n. m. could be an AI Nov 04 '21 at 19:06
  • The `delete[]` is working, unfortunately there are no guarantees of what happens to an allocation that has been `delete`ed. You've promised to not use it again with the `delete`, but if you break that promise maybe the data will still be there, maybe it won't. Maybe the system will have reclaimed the memory and the program crashes, maybe it won't. Don't break the promise. – user4581301 Nov 04 '21 at 19:06
  • Thanks for everbody, I understand it now. – uk628 Nov 04 '21 at 19:25
  • (1) Run it with `valgrind`. It will list all your memory management problems. (2) Don’t allocate anything unless you have to. (You don’t have to.) (3) Why not just a `std::string contents[2][3]` on the stack? Why the intermediate pointers (or any pointers) when `contents[i]` are of the same size and the whole array is small? (4) You don’t want to use raw pointers anyway. How about `std::vector>`? (5) If you insist on some (almost) manual allocation, why not `std::unique_ptr[]>`? That will call `delete[]` for you when the time is right. – Andrej Podzimek Nov 04 '21 at 19:57

0 Answers0