CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    May 2002
    Posts
    1,798

    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

  2. #2
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    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

  3. #3
    Join Date
    Jun 2002
    Location
    Stockholm, Sweden
    Posts
    1,641

    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

  4. #4
    Join Date
    May 2002
    Posts
    1,798

    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

  5. #5
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    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;
    }

  6. #6
    Join Date
    Jun 2002
    Location
    Stockholm, Sweden
    Posts
    1,641

    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

  7. #7
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: quadruple pointer problem

    Quote Originally Posted by zerver View Post
    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.

  8. #8
    Join Date
    May 2002
    Posts
    1,798

    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
  •  





Click Here to Expand Forum to Full Width

Featured