-
September 7th, 2015, 02:58 PM
#1
quadruple pointer problem
I wish to use a double **** in order to cross an application to dll boundary using a plain old data type. I have done this successfully with double ** and double *** pointers. However, allocating double **** has been a problem.
Here's the code I have developed:
Code:
double **** Allocate4(double **** mat, int k, int l, int m, int n)
{
mat = new double *** [ sizeof(double) * k * l * m * n ];
for(int i = 0; i < k; i++)
mat[i] = new double **[ sizeof(double) * l * m * n ];
for(int i = 0; i < l; i++)
{
for(int j = 0; j < m; j++)
{
mat[i][j] = new double *[ sizeof(double) * m * n ];
}
}
for(int i = 0; i < k; i++)
{
for(int j = 0; j < l; j++)
{
for(int q = 0; q < m; q++)
{
mat[i][j][q] = new double [ sizeof(double) * n ];
}
}
}
return mat;
}// Allocate4(double **** mat, int k, int l, int m, int n)
void DeAllocate4(double **** mat, int k, int l, int m, int n)
{
for(int i = 0; i < k; i++)
{
for(int j = 0; j < l; j++)
{
for(int q = 0; q < m; q++)
{
delete mat[i][j][q]; mat[i][j][q] = NULL;
}
}
}
for(int i = 0; i < l; i++)
{
for(int j = 0; j < m; j++)
{
delete mat[i][j]; mat[i][j] = NULL;
}
}
for(int i = 0; i < k; i++)
{
delete mat[i]; mat[i] = NULL;
}
delete mat; mat = NULL;
}// DeAllocate4(double **** mat, int k, int l, int m, int n)
Attempting to use this code, I find that there are boundary violations with certain combinations of the input parameters, k, l, m, n. For example, etc.
res k l m n
- 3 1 12 12
+ 3 3 12 12
- 2 3 12 12
- 4 3 3 3
- 3 4 3 3
- 4 4 3 3
+ 4 4 4 4
+ 12 12 12 5
+ 12 12 12 6
- 12 12 6 12
- 12 12 6 6
- 11 11 6 6
Using VS 2010 debugger, when crash occurs, typically looks like this:
mat[i][j] = new double *[ sizeof(double) * m * n ];
[-] mat 0x00470068
[-] 0x0060bd40
[-] 0x0047a2e8
[-] 0xcdcdcdcd
(!) CXX0030: Error: expression cannot be evaluated
First-chance exception at 0x0fa3be1f (ctap.dll) in MyApp.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
Unhandled exception at 0x0fa3be1f (ctap.dll) in MyApp.exe: 0xC0000005: Access violation writing location 0xcdcdcdcd.
The program '[0x1BA8] MyApp.exe: Native' has exited with code -1073741819 (0xc0000005).
Here's an example program for illustration:
Code:
int main()
{
int iOrg = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
_CrtSetDbgFlag(iOrg | _CRTDBG_LEAK_CHECK_DF);
double **** pfTensor4;
int k, l, m, n;
k = 10; l = 11; m = 6; n = 6; // error at: mat[i][j] = new double *[ sizeof(double) * m * n ];
pfTensor4 = NULL;
pfTensor4 = Allocate4(pfTensor4, k, l, m, n);
srand (time(NULL));
for(int i = 0; i < k; i++)
{
for(int j = 0; j < l; j++)
{
//printf("Index(%d)\n", i);
_RPT2(0, "Index(%d, %d)\n", i, j);
for(int q = 0; q < m; q++)
{
for(int r = 0; r < n; r++)
{
pfTensor4[i][j][q][r] = (double)rand()/rand();
//printf("%0.5f ", pfTensor3[i][j][q][r]);
_RPT1(0, "%0.4f ", pfTensor4[i][j][q][r] );
}
_RPT0(0, "\n");
}
//printf("\n");
_RPT0(0, "\n");
}
}
//printf("\n");
_RPT0(0, "\n");
DeAllocate4(pfTensor4, k, l, m, n);
#ifdef _DEBUG
cout << "Press Enter to continue... ";
cin.get();
#endif
return 0;
}// main()
I believe there is a problem with the quadruple pointer allocator, but I cannot find what it is. Can anyone help me to properly allocate / deallocate such a pointer? Thank you.
Last edited by Mike Pliam; September 7th, 2015 at 06:43 PM.
Reason: add example program
mpliam
-
September 8th, 2015, 09:48 AM
#2
Re: quadruple pointer problem
1) why are you using new with sizeof(double) ?
it could be intended (usage doesn't agree with that), but more likely this is a leftover artefact from code that was written for malloc().
2) your delete calls should be delete[] calls.
you don't need to set a pointer to NULL after deleting it.
especially considering that moments later, you're deallocating the memory you just explicitely set to NULL.
3) why is mat an input parameter in the Allocate4() ? the first thing you do is overwrite the input value.
why are you both retuning the allocated memory by pointer, and accepting it via an output parameter.
the bug:
your 2Nd loop in Allocate4 is wrong.
Code:
for(int i = 0; i < l; i++) -> must be i<k
for(int j = 0; j < m; j++) -> must be j<l
-
September 8th, 2015, 10:05 AM
#3
Re: quadruple pointer problem
Did not test, but something like this:
Code:
double **** Allocate4(double **** mat, int k, int l, int m, int n)
{
mat = new double *** [k];
for(int i = 0; i < k; i++) {
mat[i] = new double **[l];
}
for(int i = 0; i < k; i++) {
for(int i2 = 0; i2 < l; i2++) {
mat[i][i2] = new double *[m];
}
}
for(int i = 0; i < k; i++) {
for(int i2 = 0; i2 < l; i2++) {
for(int i3 = 0; i3 < m; i3++) {
mat[i][i2][i3] = new double [n];
}
}
}
return mat;
}
Nobody cares how it works as long as it works
-
September 8th, 2015, 10:33 AM
#4
Re: quadruple pointer problem
Thank you, Zerver, for your kind help. Your code works flawlessly as far as I can tell.
Here's some deallocation code for anyone who is interested.
Code:
void DeAllocate4(double **** mat, int k, int l, int m, int n)
{
for(int i = 0; i < k; i++) {
for(int i2 = 0; i2 < l; i2++) {
for(int i3 = 0; i3 < m; i3++) {
delete [] mat[i][i2][i3];
}
}
}
for(int i = 0; i < k; i++) {
for(int i2 = 0; i2 < l; i2++) {
delete [] mat[i][i2];
}
}
for(int i = 0; i < k; i++) {
delete [] mat[i];
}
delete [] mat;
}// DeAllocate4(double **** mat, int k, int l, int m, int n)
mpliam
-
September 9th, 2015, 06:47 AM
#5
Re: quadruple pointer problem
could do it all with 1 set of loops instead of 3.
Code:
double **** Allocate4(int k, int l, int m, int n) //<-- don't need mat as input parameter
{
double **** mat = new double *** [k];
for (int ik = 0; ik < k; ++ik)
{
mat[ik] = new double **[l];
for (int il = 0; il < l; ++il)
{
mat[ik][il] = new double *[m];
for (int im = 0; im < m; ++im)
{
mat[ik][il][im] = new double [n];
}
}
}
return mat;
}
-
September 9th, 2015, 09:51 AM
#6
Re: quadruple pointer problem
Correct, but if we are going down the optimization route, more importantly you wouldn't call "new" so many times.
Instead make one allocation for each dimension, and the elements would then index into that buffer.
double *mat = new double [k*l*m*n];
double **matp = new double *[k*l*m];
double ***matpp = new double **[k*l];
double ****matppp = new double ***[k];
or, if you can accept some casting, you can even do it all in one go
void *mem = (void *)malloc( k*l*m*n * sizeof(double) + (k*l*m + k*l + k) * sizeof(void*));
Nobody cares how it works as long as it works
-
September 9th, 2015, 04:49 PM
#7
Re: quadruple pointer problem
Originally Posted by zerver
Correct, but if we are going down the optimization route, more importantly you wouldn't call "new" so many times.
true, but that changes the organisation of things, and he needs it this way for communication with a dll that probably wants it to be an array of pointers to arrays of pointers to arrays of pointers to arrays of pointers to arrays of double.
But yeh, not only does this require a ton of new s (which are slow), there's also ton of overhead in pointers to something.
-
September 12th, 2015, 02:03 PM
#8
Re: quadruple pointer problem
Thank you for you most helpful and informative comments. I have long wondered about mixing malloc and new, but have tended never to mix them. Since most of my dll underlying code as well as the calling app code uses new, I never use malloc, which is C code, not C++. On the other hand, the dll wrapper is C. I came across this comment in the source code page for a double quadruple pointer (which turns out to have serious limitations).
When you new an object, space for the object is not only allocated but the
object's constructor is called. And similarly when you delete an object,
the object's destructor is called before the memory is released. If you
use malloc and free, the destructor and constructor do not get called
respectively and obviously, this simply won't do in C++ except in certain
very rare situations where you have classes without any specific destructor/constructors.
see: http:http://www.codeproject.com/Articles/...ix-them-is-sin
mpliam
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|