Archived

This topic is now archived and is closed to further replies.

remi

pointer's problem

Recommended Posts

this code compiles fine but i have an error message at run-time
  
int main()
{
	int a[2][2]={45,65,45,65};
	int **b;
	b=(int **)a;
	b[0][0]=5;// The error occurs here

	return 0;
}
  
What's the reason of that? Appreciate anyhelp! [edited by - remi on November 1, 2002 12:33:52 PM]

Share this post


Link to post
Share on other sites
I believe that ''a'' is an int*, not an int**. It compiles fine because you are casting to an int** so that the assignment to ''b'' is legal. Change ''b'' from an int** to an int*, drop the cast, and I think you''ll be all set. Good luck!

-Glyph

Share this post


Link to post
Share on other sites
Glyph it works but "b[0][0]=9" becomes invalid.
Yes i know u could change it by b[0]=9, but ''a'' is an int *, ''b'' too, i can write a[0][0] so why couldn''t i do the same for ''b''?
Sorry if u get annoyed by my stupid questions

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
#include <iostream>
using namespace std;

int main()
{
int a[2][2]={45,65,45,65};
int *b;
b=(int *)a;
*b=int(5);// The error occurs here
cout << "B[0][0]=" << *b << endl;
return 0;


Try this...

Share this post


Link to post
Share on other sites
Actually,i need a two dimension pointer that can keep track of the two dimension array(it''s elements), so that i can know all the modifications inside the array without needing to implicitly asking from it.
U may ask me to find a different way to achieve that,but i want it like that because the pointer and the array are in two differents classes.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Well...in reality there is no such thing as a two dimensional array. When the array is allocated in memory, its allocated as a regular array would be. ie. A[2][2] == A[4] in memory.
Therefore if *b = A[2][2] then....
*b == A[0][0] *b+1 == A[0][1] *b+2 == A[1][0] *b+3 == A[2][2]

As to creating a two dimensional pointer...im not sure how this would be implemented, but the way that is mentioned above would be easier to use IMO.

Good Luck

Share this post


Link to post
Share on other sites
If you want to make b point to a and be able to access the multidimensional array through b using the same syntax as with a, you must make b of the type pointer to a two dimensional array with 2 columns. If it doesn't know there are 2 columns, it doesn't know how much to offset for each row!

You can do this with the syntax:

int (*b)[2][2];
b = &a;

Then, you can do things like

b[0][0] = 1;

b[1][1] = 4;

etc. and everything will work fine!

The reason you can't access it through a pointer to a pointer to an int is because the expression a represents a pointer to the first element, so, if you did it your way with a pointer to a pointer, what would be happening is b[0] returns a pointer and then the additional [0] would mean that it would offset 0 from the memory location being pointed to from there. So, using your example, b[0][0] would be thought of by the compiler as:

Starting at the address of a, offset 0 integers and you'll get a memory location, then offset 0 integers from the memory location POINTED to by that pointer. So it would actually attempt to write your value 5 to the memory location 45 as you defined it in your array.

Using that logic, you can force a result of your b[0][0] expression without an error (though certainly not a correct way), by making the [0][0] element of a a pointer to that location typecast to an int (because they are both 4 byte values in most cases).

IE. a[0][0] = int(&a[0][0]);

then, b[0][0] would actually work (depending on what you mean by work that is...) and you won't get a runtime error.

Of course, though, if you were to do it like that, you would have to have a pointer typecast to an integer for each dimension, and they wouldn't be pointing to their own locations, you'd want them to point to locations further down in the array.

So, in short, use the

int (*b)[2][2] = &a;

which I mentioned earlier. It's the best, most portable way of doing it, gives you access to a as a multidimensional array while retaining the lengths of the dimensions.

[edited by - Matt Calabrese on November 1, 2002 2:09:18 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Anonymous Poster
*b == A[0][0] *b+1 == A[0][1] *b+2 == A[1][0] *b+3 == A[2][2]



Also, AP''s WOULD be a good representation of how to access the array through pointer notation except he screwed up his operator precidence. The CORRECT way of doing pointer notation would have been

*(b)
*(b+1)
*(b+2)
*(b+3)

He left out the parenthesis, so rather than accessing the different elements you would have just been adding values to the first element and actually wouldn''t have been doing pointer arithmentic at all.

Another way you could look at accessing the array is, using that same logic, the pattern

int a[numrows][numcols]

a[row][column] = &a[0][0] + row * numcols + column

this can be better understood by looking at the matrix a as an array of numrows arrays of length numcols, so every numcols worth of elements is the beginning of the next dimension. row * numcols gives you the 0th element of that row and adding column gives you the colum of that array.

Only use that method if you don''t know the dimensions of the array at runtime (IE if you dynamically allocate the array), or if you are passing the array to a function in which the lengths of the dimensions can vary.

Again, the original method I mentioned is probably the best way

int (*b)[2][2]

and it''s also the most readable when accessing elements -- ESPECIALLY when dealing with arrays of more than 2 dimensions (in which manually calculating the address becomes very drawn out and unreadable).

Share this post


Link to post
Share on other sites
Thanx all for anyhelp u gave, I tried to make a resume of all the methods u proposed and then according to the specific problem i had i decided to use this:
int a[VER_NUM][HOR_NUM];
int *b;
b=a;
And then to get the value of a[y][x], i just need to do:
b[y*VER_NUM+x]. It works and it''s quite smart for what i''m doing.

Nevertheless i tried something Matt Calabrese proposed but when doing this:
int (*b)[2][2];
b = &a;
Then b[0][0] = 1; becomes an invalid code, because b[0][0] is like a pointer.

Once again thanx all

Share this post


Link to post
Share on other sites
Oh, woops.

Yeah, you can do it the way I mentioned, but I forgot that array pointers aren''t auto-dereferencing (unlike functions).

My way will work, how every you do have to explicitly dereference:

(*b)[0][0] = 1

will work.

However, there is a much easier way to do it, without having to dereference it. Do this:

int (*b)[2] = a; // Which for us will represent a pointer to an array of 1 dimensional integer arrays of length 2

you will now be able to do:

b[0][0] = 1;

with not problem at all.

Share this post


Link to post
Share on other sites