pointer to a two dimentional array - c++

How can I let a pointer assigned with a two dimensional array?
The following code won't work.
float a1[2][2] = { {0,1},{2,3}};
float a2[3][2] = { {0,1},{2,3},{4,5}};
float a3[4][2] = { {0,1},{2,3},{4,5},{6,7}};
float** b = (float**)a1;
//float** b = (float**)a2;
//float** b = (float**)a3;
cout << b[0][0] << b[0][1] << b[1][0] << b[1][1] << endl;

a1 is not convertible to float**. So what you're doing is illegal, and wouldn't produce the desired result.
Try this:
float (*b)[2] = a1;
cout << b[0][0] << b[0][1] << b[1][0] << b[1][1] << endl;
This will work because two dimensional array of type float[M][2] can convert to float (*)[2]. They're compatible for any value of M.
As a general rule, Type[M][N] can convert to Type (*)[N] for any non-negative integral value of M and N.

If all your arrays will have final dimension 2 (as in your examples), then you can do
float (*b)[2] = a1; // Or a2 or a3

The way you do this is not legit in c++. You need to have an array of pointers.

The problem here is that the dimensions of b are not known to the compiler. The information gets lost when you cast a1 to a float**. The conversion itself is still valid, but you cannot reference the array with b[][].

You can do it explicitly:
float a1[2][2] = { {0,1},{2,3}};
float* fp[2] = { a1[0], a1[1] };
// Or
float (*fp)[2] = a1;

Try assigning b to be directly equals to a1, that's mean that the pointer b is pointing to the same memory location that pointer a1 is pointing at, they carry the same memory reference now, and you should be able to walk through the array.

Related

Pointer Arithmetic (adding ints to arrays)

So I read online that if you have an array like
int arr[3] = {1,2,3}
I read that if you take (arr+n) any number n it will just add sizeof(n) to the address so if n is an integer(takes up 4 bytes) it will just add 4 right? But then I also experimented on my own and read some more stuff and found that
arr[i] = *(arr+i) for any i, which means it's not just adding the sizeof(i) so how exactly is this working?
Because obviously arr[0] == *(arr+0) and arr[1] == *(arr+1) so it's not just adding sizeof(the number) what is it doing?
I read that if you take (arr+n) any number n it will just add sizeof(n) to the address
This is wrong. When n is an int (or an integer literal of type int) then sizeof(n) is the same as sizeof(int) and that is a compile time constant. What actually happens is that first arr decays to a pointer to the first element of the array. Then sizeof(int) * n is added to the pointers value (because elements type is int):
1 2 3
^ ^
| |
arr arr+2
This is because each element in the array occupies sizeof(int) bytes and to get to memory address of the next element you have to add sizeof(int).
[...] and read some more stuff and found that arr[i] = *(arr+i)
This is correct. For c-ararys arr[i] is just shorthand way of writing *(arr+i).
When you write some_pointer + x then how much the pointer value is incremented depends on the type of the pointer. Consider this example:
#include <iostream>
int main(void) {
int * x = 0;
double * y = 0;
std::cout << x + 2 << "\n";
std::cout << y + 2 << "\n";
}
Possible output is
0x8
0x10
because x is incremented by 2* sizeof(int) while y is incremented by 2 * sizeof(double). Thats also the reason why you get different results here:
#include <iostream>
int main(void) {
int x[] = {1,2,3};
std::cout << &x + 1 <<"\n";
std::cout << &x[0] + 1;
}
However, note that you get different output with int* x = new int[3]{1,2,3}; because then x is just a int* that points to an array, it is not an array. This distinction between arrays and pointers to arrays causes much confusion. It is important to understand that arrays are not pointers, but they often do decay to pointers to their first element.

NTL Library: How to assign a big integer to ZZ_p

In NTL library I know that we can define a big integer value as:
ZZ p;
p=to_ZZ("1111111111111111111111111111111333333333333333");
ZZ_p::init(p);
ZZ_p b(12);
My question is: What if I want to assign a big integer to b rather than 12 ?
e.g.
ZZ_p b("1111111111111111111111111111111333333333333334");
So it should modulo p and assign 1 to b.
I need it for fFindRoots(vec_ZZ_p& x, const ZZ_pX& ff), so would be able to insert big integers to a vector as coefficients (of a polynomial)
First: I tried the code you posted and the line ZZ_p b(12); did not work for me.
I had to use
ZZ_p b;
b = 12;
If you want to assign a big integer you can do this by
ZZ_p b;
b = to_ZZ_p(conv<ZZ>("1111111111111111111111111111111333333333333334"));
or
char bigInteger[47] = "1111111111111111111111111111111333333333333334";
ZZ_p b;
b = to_ZZ_p(conv<ZZ>(bigInteger));
cout << b << endl; will now print 1.

Pointer to member variable

The following program output is always 1 1 1. In "Inside the c++ object model" book, it is mentioned that it will give offset. The purpose is also to find out object layout. But, I am confused with the output. Used g++ 4.5.2
class Test
{
public:
float a;
float b;
float c;
};
int main()
{
float Test::*ptr = &Test::a;
float Test::*ptr1 = &Test::b;
float Test::*ptr2 = &Test::c;
cout<<ptr<<endl;
cout<<ptr1<<endl;
cout<<ptr2<<endl;
return 0;
}
Output:
1
1
1
Edit(Follow up question):
In the book it is mentioned that origin.y = 0 can be transformed to &origin + (Point3d::y-1) where origin is an object to Point3d and y is member variable of class Point3d. Though When I compiled it gave me compilation error.
You cannot print pointers to members, but pointers to members can implicitly be converted to bool, and those can be printed, of course. The null pointer is converted to false, and all other pointers are converted to true. By default, std::cout prints false as 0 and true as 1.
You wrote that you wanted to find the memory offset. While what FredOverflow writes is completely true, you should make an instance of your class Test if you want to know the address of a,b and c. For instance:
Test t;
float *ptr = &t.a;
float *ptr1 = &t.b;
float *ptr2 = &t.c;
On my machine this yields the following three addresses:
0x7fff564f8918
0x7fff564f891c
0x7fff564f8920
And you will notice that they are 4 bytes (or sizeof(float)) apart and that the size of a Test is 12 bytes (using sizeof(Test)). Furthermore, the address of &t is 0x7fff564f8918 the same address of &t.a. That's how the memory layout of an instance of the class Test is formed.
You can also find the offset of members of a POD type by using offsetof().
cout << offsetof(Test, a) << endl;
cout << offsetof(Test, b) << endl;
cout << offsetof(Test, c) << endl;
Yields
0
4
8
Note that offsetof(Test, b) is essentially the same as
(unsigned long long) &(((Test*) 0)->b) - (unsigned long long) (Test*) 0
Answer to your followup question:
That code will not work because of the same errors as previously mentioned. However, if you wanted to calculate the address of your y member of origin and assign it the value 0 it can be done thusly:
class Point3d {
public:
float x, y, z;
};
Point3d origin;
origin.y = 10;
// We take the address of origin, which points to the first member,
// then add the offset to the member y.
float *ptr = (float*) ((unsigned long long) &origin + offsetof(Point3d, y));
cout << "Old value: " << *ptr << endl;
*ptr = 0;
cout << "New value: " << *ptr << endl;
Yields the output:
Old value: 10
New value: 0
Again remember that this is only possible because Point3d is a POD type.

memory location of pointer variable itself?

Is it possible to find the memory location of a pointer variable itself?
i.e. I don't want to know the memory location the pointer is referencing, I want to know what the memory location of the pointer variable is.
int A = 5;
int *k = &A;
cout << k;
will give me the location of A. Does k have a location?
The location of int *k is &k, like so:
// For this example, assume the variables start at 0x00 and are 32 bits each.
int A = 9; // 0x00 = 0x09
int * k = &A; // 0x04 = 0x00
int ** k_2 = &k; // 0x08 = 0x04
// Thus:
cout << "Value of A: " << A; // "Value of A: 9"
cout << "Address of A: " << k; // "Address of A: 0x00"
cout << "Address of k: " << k_2; // "Address of k: 0x04"
assert( A == *k);
assert(&A == k);
assert(&A == *k_2);
assert( A == **k_2);
assert( k == *k_2);
assert(&k == k_2);
A pointer is a variable, 32-bit on 32-bit binaries and 64 in 64, storing a memory address. Like any other variable, it has an address of its own, and the syntax is identical. For most intents and purposes, pointers act like unsigned ints of the same size.
Now, when you take &k, you now have an int **, with all the interesting complexities that go with that.
From int ** k_2 = &k, *k_2 is k and **k_2 is *k, so everything works about how you'd expect.
This can be a useful way to handle creating objects cross-library (pointers are rather fundamental and mostly safe to pass). Double pointers are commonly used in interfaces where you want to pass a pointer that will be filled with an object, but not expose how the object is being created (DirectX, for example).
Yes. You can use &k to print out the memory location of *k.
int A = 5;
int *k = &A;
cout << k;
A's address is k;
k's address is &k.
Yo dawg, we put an address at your address so you can address while you address.

Pointer to pointer array understanding problem

This is probably a stupid question, but I don't understand why this works:
int** test = new int*[7];
int x = 7;
*(test+1) = &x;
cout << (**(test+1));
test is a pointer to a pointer right? The second pointer points to the array, right?
In my understand I would need to dereference the "test" pointer first to get to the pointer that has the array.
(*test) // Now I have int*
*((*test) + 1) // to access the first element.
Where is my faulty thinking?
int** test = new int*[7];
+------++------++------++------++------++------++------+
| int* || int* || int* || int* || int* || int* || int* |
+------++------++------++------++------++------++------+
is the equivalent of an array with int pointers:
int* test[0]
int* test[1]
...
int* test[6]
this
int x = 7;
*(test+1) = &x;
+------++------++------++------++------++------++------+
| int* || &x || int* || int* || int* || int* || int* |
+------++------++------++------++------++------++------+
is the same as
int x = 7;
test[1] = &x
so now one of the pointers in your original array is pointing the memory location of x
cout << (**(test+1));
is the same as
cout << *test[1]
which is the value of x (==7) and which both test[1] and &x point to.
Is your misunderstanding that you think you have created a pointer to an array of 7 int? You haven't. You actually have created an array of 7 pointers to int. So there is no "second pointer" here that would point to an array. There is just one pointer that points to the first of the 7 pointers (test).
And with *test you get that first pointer which you haven't initialized yet, though. If you would add 1 to that, you would add 1 to some random address. But if you add 1 to test you get a pointer that points to the second pointer of the array. And dererencing that you get that second pointer, which you did initialize.
What you describe would be achieved by a different syntax
typedef int array[7];
array* test = new int[1][7];
// Note: "test" is a pointer to an array of int.
// There are already 7 integers! You cannot make it
// point to an int somehow.
*(*test + 1) = 7;
int *p1 = *test
int i1 = *(p1 + 1); // i1 is 7, second element of the int[7]
delete[] test;
Without using the typedef, this looks like the following
int(*test)[7] = new int[1][7];
That is, you have created a one-element array, where the element-type of that is a 7-element array of int. new gives you a pointer back to that array. Note that the parenthesis is important: The * has less precedence than the [7], so otherwise this would be taken as an array of 7 pointer to integers.
Suppose that
test[0] = 0x12345678; // some pointer value
test[1] = 0x23456789; // some pointer value
*test = 0x12345678;
*test + 1 is now 0x12345678 + 1 = 0x12345679;
* or dereference operator has higher precedence than binary +). So the expression is evaluated in that order.
However what you wanted for is to get to test[0] = 0x23456789;
So the correct expression to get to test[1] = (*(test + 1))
In general arr[i] is *(arr + i)
EDIT 2:
given
int buf[10] = {0, 1, 2};
int *p = buf;
buf[0] == p[0] == *(p + 0) equal to 0.
Note that it is perfectly fine to use array access syntax with the lvalue expression p even if it is not an array type. In fact the expression buf[0] is internally translated by the compiler to *(buf + 0) as well.
The expression *(test + 1) is equivalent to test[1], so your code could be rewritten thus:
int** test = new int*[7];
int x = 7;
test[1] = &x;
cout << *test[1];
Since test[1] obviously points to x, *test[1] is 7.
Just to be clear, the expression **(test + 1) is simply equivalent to *(*(test + 1)), which is in turn equivalent to *test[1].