When I use a string type dynamic 2D array, there is memory leak after deleting the array. Please view the following code:
#include <string>
using namespace std;
#define NEW2D(H, W, TYPE) (TYPE **)new2d(H, W, sizeof(TYPE))
void* new2d(int h, int w, int size)
{
register int i;
void **p;
p = (void**)new char[h*sizeof(void*) h*w*size];
for(i = 0; i < h; i )
{
p[i] = ((char *)(p h)) i*w*size;
}
return p;
}
If I use the following code:
string** pstr = NEW2D(2, 4, string);
memset(pstr[0], 0, sizeof(string)*2*4);
delete [] pstr;
There is no memory leak; however, if I use the following code:
string** pstr = NEW2D(2, 4, string);
memset(pstr[0], 0, sizeof(string)*2*4);
for (int j = 0; j < 2; j )
for (int i = 0; i < 4; i )
pstr[j][i] = "test";
for (int j = 0; j < 2; j )
for (int i = 0; i < 4; i )
pstr[j][i].clear();
delete [] pstr;
The memory leak is happened, even if I have called pstr[j][i].clear().
What should I do to avoid memory leak after having
for (int j = 0; j < 2; j )
for (int i = 0; i < 4; i )
pstr[j][i] = "test";
in my code?
CodePudding user response:
The problem with your code because it treats non-trivial types like std::string
as if they were trivial. Probably you could create something using placement new that was legal C and worked in a similar way to the code you've written
But here's an simple alternative that (hopefully) works
template <typename T>
T** new2d(int h, int w)
{
T** p = new T*[h];
T* q = new T[h*w];
for (int i = 0; i < h; i )
p[i] = q i*w;
return p;
}
And to delete
template <typename T>
void free2d(T** p, int h)
{
if (h > 0)
delete[] p[0];
delete[] p;
}
Untested code.
CodePudding user response:
Thanks to John. I have tried the following code, it works well:
int i;
int data_height = 2, data_width = 4;
string **data;
data = new string*[data_height];
for(i = 0; i < data_height; i )
data[i] = new string[data_width];
for (int j = 0; j < 2; j )
for (int i = 0; i < 4; i )
data[j][i] = "test";
for(i = 0; i < data_height; i )
delete [] data[i];
delete [] data;