C/C++ Help
 
Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
 
User Name:
Password:
Remember me
 



Go Back   Dev Articles Community ForumsProgrammingC/C++ Help

Reply
Add This Thread To:
  Del.icio.us   Digg   Google   Spurl   Blink   Furl   Simpy   Y! MyWeb 
Thread Tools Search this Thread Display Modes
 
Unread Dev Articles Community Forums Sponsor:
  #1  
Old December 5th, 2004, 08:33 AM
rookie rookie is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Dec 2004
Posts: 1 rookie User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: < 1 sec
Reputation Power: 0
Memory & arrays - c++ pointer to multidimensional array

Hi!
I am trying to use a multidimensional pointer to a multidimensional array, but I am not able to make it work (unfortunately...). I know that I can assign a pointer to an array by

int *ptr = new int[5];

My problem is that I want to have a multidimensional array and

object (*ptr)[10] = new object[5][10];
or
object (*ptr)[10][15] = new object[5][10][15];

gives me some trouble. Compiling my code with gcc-3.3 results in

error: base operand of `->' has non-pointer type `object'

when I try to work with the object. Any idea will be greatly appreciated. Thanks in advance.

Reply With Quote
  #2  
Old December 5th, 2004, 12:58 PM
kode_monkey kode_monkey is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jul 2003
Posts: 367 kode_monkey User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 7 m 21 sec
Reputation Power: 15
You can use multiple *'s to show multiple dimensions so -

Code:
object ***ptr = new object[5][10][15];


Basically match the number of *'s to the number of []'s you have.

-KM-

Reply With Quote
  #3  
Old February 11th, 2005, 05:53 AM
naputan naputan is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2005
Posts: 1 naputan User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 17 m 56 sec
Reputation Power: 0
Quote:
Originally Posted by kode_monkey
You can use multiple *'s to show multiple dimensions so -

Code:
object ***ptr = new object[5][10][15];


Basically match the number of *'s to the number of []'s you have.

-KM-


This won't work. When I do 'cl /EHsc test.cpp' (MS c++ compiler v.13.10.3077)
I get:

"test.cpp(5) : error C2440: 'initializing' : cannot convert from 'float (*)[10][15]' to 'float *** '
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast2"

Code:
#include <iostream>
usingnamespace std;
 
int main() {
		float ***ptr = newfloat[5][10][15];
}

Reply With Quote
  #4  
Old February 11th, 2005, 08:52 AM
Anibal Anibal is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jan 2005
Posts: 176 Anibal User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 4 h 20 m 48 sec
Reputation Power: 14
Hey Mate! Look, this is more like a c solution. If you allready know the size of your multidimensional array, lets say [5][5][5] you can do:

Code:
#includes....
 
typedef float matrix[5][5][5]; 
 
int main(){
	matrix *ptr;
	//asigning a value just to test it
	*ptr[0][0][0] = 63.5;
	....
	....
	....
}



Good Luck..

Anibal.

Reply With Quote
  #5  
Old February 13th, 2005, 11:48 PM
BoolBooB BoolBooB is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Feb 2005
Posts: 36 BoolBooB User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 9 h 35 m 42 sec
Reputation Power: 14
You can't get there from here

When you create a multidimensional array in C/C++ using array notation such as:
int array[10][10];
the compiler sets up some pointers behind the scenes that you are not aware of.
If you want to do the same using pointer notation you have to create and initialize
these pointers or you wont get the desired results.

Here's an example of a C function that dynamically creates a two dimensional array of ints
from a passed in pointer. Note that in this example both dimensions of the array
are the same (it was modeling a square).
It helps to think of the array in terms of rows/collumns. You have to set up the row
pointers and initialize them.

int allocateMatrix(int ***matrixPtr, int order) {

int i, j; // temporary counter

*matrixPtr = (int **) calloc (order, sizeof(int));
if (*matrixPtr == (int **) NULL) {
printf("Error allocating memory for row pointer \n");
return(MEMORY_ERROR);
}

**matrixPtr = (int *) calloc (order * order, sizeof(int));
if (**matrixPtr == (int *) NULL) {
printf("Error allocating memory for array \n");
return(MEMORY_ERROR);
}

// initialize our row pointers to allow array indexing into our array
for (i = 0, j = 0; i < order; i++, j += order) {
*(*matrixPtr + i) = (**matrixPtr + j);
}
return (SUCCESS);
}

Here's a snuiplet from main that shows the definition of our arrary pointer and the call to
allocateMatrix.

int main(int argc, char **argv)
{
long int order; // order of array (rows and columns
int **matrixPtr; // pointer to our magic square
.
.
.


// Allocate memory for our magic square
if (allocateMatrix(&matrixPtr, order) != (SUCCESS)) {
printf("Error allocating memeory for magic square\n");
exit(MEMORY_ERROR);
}

At this point you can use matrixPtr as if it were a two dimensional array:
matrixPtr[2][3] = 1;

Reply With Quote
  #6  
Old June 26th, 2006, 11:33 AM
jonawebb jonawebb is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jun 2006
Posts: 1 jonawebb User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 13 m 24 sec
Reputation Power: 0
Pointer to multidimensional array

Setting up an array of pointers is one way to accomplish something similar to the original question, but it is not the best way. An array of pointers requires an additional memory reference for each dimension, and creating and destroying the array requires a loop.

C++ directly supports an answer to the original question, however. The syntax is a bit tricky, and I always end up using a typedef to simplify it.

The trick is to parenthisize the pointer declaration. This informs C++ that you want a pointer to an array, rather than array of pointers.

So writing
int (*a)[10];
declares that a is a pointer to an array of 10 ints. By constrast,
int *a[10];
declares that a is an array of 10 pointers to ints.

To get back to the original question, instead of writing
object (*ptr)[10] = new object[5][10];
or
object (*ptr)[10][15] = new object[5][10][15];

you must write
typedef object (*ObjectArray)[5][10][15];
ObjectArray ptr = (ObjectArray) new object[5][10][15];
You would also have to dereference the array whenever you refer to an element. For example,
(*ptr)[4][3][2] = 0;

Reply With Quote
  #7  
Old July 3rd, 2006, 01:10 PM
one4mtl one4mtl is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jul 2006
Location: Alexandria, VA
Posts: 1 one4mtl User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 8 m 24 sec
Reputation Power: 0
Thumbs up

jonawebb, you are the man! Thanks for helping me solve an annoying problem I was having trying to return a multidimensional array.

Reply With Quote
  #8  
Old May 17th, 2007, 12:11 PM
obtt obtt is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: May 2007
Posts: 2 obtt User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 59 m 3 sec
Reputation Power: 0
For Jonawebb

joneawebb,
I have a question about array pointer:
How to declare dynamic pointer to char (*a) [x], where x is string array to be determined during program process.
Thanks

Reply With Quote
  #9  
Old May 17th, 2007, 12:31 PM
obtt obtt is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: May 2007
Posts: 2 obtt User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 59 m 3 sec
Reputation Power: 0
For Jonawebb

To be clear:
char (*a)[x] x is number of string arrays which will be determined during program process (X will be determined during program process also).
Thanks

Reply With Quote
  #10  
Old June 20th, 2007, 11:27 PM
jeffareid jeffareid is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jun 2007
Posts: 2 jeffareid User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 h 15 m 18 sec
Reputation Power: 0
These examples work fine with Microsoft Compiler (Visual C 4.0 and Visual Studio 2005), without requiring the extra level of indirection:

C++ matrix example:

Code:
    double (*pmd)[5] = new double[4][5];
    pmd[1][2] = 1.0;
    delete [] pmd;


C++ array with matrix typecast example:
Code:
    double *pad = new double[20];
    ((double (*)[5])pad)[1][2] = (double) 1.0;
    delete []pad;


C matrix:
Code:
    double (*pmd)[5] = (void *)malloc(4*5*sizeof(double));
    pmd[1][2] = 1.0;
    free(pmd);


C array with matrix typecast:

Code:
    double *pad = (void *)malloc(4*5*sizeof(double));
    ((double (*)[5])pad)[1][2] = 1.0;
    free((void *)pad);


Using Microsoft compiler, all 3 examples produce essentially the same code:
allocate 160 bytes,
set [ptr+56] = [ptr + (((1 x 5) + 2) x sizeof(double))] to 1.0
free ptr.

Quote:
char (*a)[x] x is number of string arrays which will be determined during program process
Visual Studio doesn't support this. All dimensions but the first dimension of a tensor have to be constants. The [5] I used in the examples above is not allowed to be replaced with an integer variable. Maybe a different C++ compiler would support this.

Reply With Quote
  #11  
Old June 22nd, 2007, 07:42 AM
nosale nosale is offline
Contributing User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: May 2007
Posts: 110 nosale User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 Day 23 m 10 sec
Reputation Power: 11
I always hated creating multi-dimensional arrays in c, or c++. First, you have to create and array of pointers, then cycle through each pointer and assign a pointer to an array for each one. If you have to go further than 2 dimensions, this gets kinda tedious. What I usually end up doing is assigning a 1-d array which is large enough to hold all the values, and write a macro for my own indexing function. For example:

c++ Code:
Original - c++ Code
  1. #define index(x,y,c) (y*c + x)
  2.  
  3. // your code in here...
  4.  
  5. int rows = 20;
  6. int cols = 20;
  7. int *2darray = new int[rows*cols];
  8.  
  9. // more code...
  10.  
  11. 2darray[index(i,j,cols)] = blah;


Which can easily be extended to n dimensions without having to worry about assigning pointers to pointers to pointers :P Just my 2 cents

EZ-E

Reply With Quote
  #12  
Old June 23rd, 2007, 03:28 AM
jeffareid jeffareid is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jun 2007
Posts: 2 jeffareid User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 1 h 15 m 18 sec
Reputation Power: 0
Might as well implement a macro as you did, since it's represents the code the compiler is going to produce anyway.

C or C++ could be extended to work with dynamic multi-dimensional arrays, as this problem was first solved back in the early 1960's with APL.

APL (A Programming Language) was the first language that handled multi dimensional variables automatically. The way variables were stored was in this format:

type of variable (bit, byte, word, dword, float, ...)
number of dimensions
size of 1st dimension
size of 2nd dimension
...
size of last dimension
data
...
data

A scalar had 0 dimensions, and was "compatable" with any size variable (you could add, subtract, mulitply, divide, compare, ..., a scalar to any size variable).

Interest in APL mostly faded in the 1980's and now Matlab is the tool of choice for most interactive math related stuff. The latest incarnation of APL is now called "J" for the diehards.

Still I messed with APL for about a year and I miss all the cool single character greek symbol operators.

Reply With Quote
  #13  
Old January 23rd, 2011, 09:08 AM
pavibhai pavibhai is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jan 2011
Posts: 1 pavibhai User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 21 m 38 sec
Reputation Power: 0
Access using multiplication for offset

Quote:
Originally Posted by jonawebb
Setting up an array of pointers is one way to accomplish something similar to the original question, but it is not the best way. An array of pointers requires an additional memory reference for each dimension, and creating and destroying the array requires a loop.

C++ directly supports an answer to the original question, however. The syntax is a bit tricky, and I always end up using a typedef to simplify it.

The trick is to parenthisize the pointer declaration. This informs C++ that you want a pointer to an array, rather than array of pointers.

So writing
int (*a)[10];
declares that a is a pointer to an array of 10 ints. By constrast,
int *a[10];
declares that a is an array of 10 pointers to ints.

To get back to the original question, instead of writing
object (*ptr)[10] = new object[5][10];
or
object (*ptr)[10][15] = new object[5][10][15];

you must write
typedef object (*ObjectArray)[5][10][15];
ObjectArray ptr = (ObjectArray) new object[5][10][15];
You would also have to dereference the array whenever you refer to an element. For example,
(*ptr)[4][3][2] = 0;


I think you can also just have the reference to the base element of the array into a pointer lets say for example
int *ptr;
ptr = &array[0][0];
After this the subsequent elements can be accessed as
*(ptr + (i * j)) where i and j refer to array[i][j]

Reply With Quote
  #14  
Old August 9th, 2011, 03:32 PM
ece85 ece85 is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Aug 2011
Posts: 1 ece85 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 9 m 2 sec
Reputation Power: 0
pavibhai - thank you for the most simple...ie best solution.

Reply With Quote
  #15  
Old January 31st, 2012, 07:52 PM
Arctic Inferno Arctic Inferno is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Jan 2012
Posts: 1 Arctic Inferno User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 37 m 37 sec
Reputation Power: 0
Address of an element vs address of the array

Quote:
Originally Posted by ece85
pavibhai - thank you for the most simple...ie best solution.

The concept of "simple", "best", "easy", "difficult", "complex", etc... all are relative.
pavibhai's example is intuitive, and will probably suffice for small tasks, but it requires multiplication and addition.
If your algorithm runs millions/billions of computations, then the time consumption may quickly become an issue.
Also, I think the code looks messy and unclean. It's a flimsy band aid solution.
jonawebb's example is the "proper" way of coding.

There's a distinction between the address of the first element of the array and the address of the whole array.
Consider the following 4-dimensional array (from an actual code).

// Allocate a large memory block and initialize it.
int someVeryLargeArr[11][11][11][2] = {{{{6,7},...};

// A pointer is created, but no memory is allocated for the array.
int (*multDimArrPtr)[11][11][11][2];

multDimArrPtr = &someVeryLargeArr; // Critical to have &.
int tmp = (*multDimArrPtr)[0][0][0][1];
// Now tmp will equal 7.

The above example creates a humongous array once, and a pointer to it is passed around.
Much more elegant than creating two arrays and copying via memcpy.
If I may reiterate, there's a distinction between the address of the first element of the array and the address of the whole array.
For more details and in-depth explanation, here's a URL link.
Oops! As a new member, I'm not allowed to post URL links.
Do a web search with "5.8. Arrays, the & operator and function".

Reply With Quote
  #16  
Old October 17th, 2012, 01:35 PM
Brighton Beach Brighton Beach is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2012
Posts: 1 Brighton Beach User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 25 m 46 sec
Reputation Power: 0
Is it legal to declare multidimensional array like that?

int *a=new int[5,5,5,5];

It translated without an error.

Reply With Quote
  #17  
Old October 18th, 2012, 08:03 PM
Sharon494 Sharon494 is offline
Registered User
Dev Articles Newbie (0 - 499 posts)
 
Join Date: Oct 2012
Posts: 5 Sharon494 User rank is Just a Lowly Private (1 - 20 Reputation Level) 
Time spent in forums: 5 m 10 sec
Reputation Power: 0
Setting up an array of pointers is one way to accomplish something similar to the original question, but it is not the best way. An array of pointers requires an additional memory reference for each dimension, and creating and destroying the array requires a loop.

Reply With Quote
Reply

Viewing: Dev Articles Community ForumsProgrammingC/C++ Help > Memory & arrays - c++ pointer to multidimensional array


Developer Shed Advertisers and Affiliates


Thread Tools  Search this Thread 
Search this Thread:

Advanced Search
Display Modes  Rate This Thread 
Rate This Thread:


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
View Your Warnings | New Posts | Latest News | Latest Threads | Shoutbox
Forum Jump

Forums: » Register « |  User CP |  Games |  Calendar |  Members |  FAQs |  Sitemap |  Support | 
  
 


Powered by: vBulletin Version 3.0.5
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.

© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap