What is meaning of (*x++) in c++? - c++

#include <iostream>
using namespace std;
class base {
public:
int* x, y;
base(int xx = 0, int yy = 0) {
x = new int[4];
for (int i = 0; i < 4; i++)
x[i] = 1;
(*x++) = xx;
y = yy++;
}
~base() { delete[] x; }
};
class Derived :public base {
public:
Derived(int xx, int yy) : base(xx), base1(yy) {
cout << (*(this->x)) << " " << this->y << " " << (*
(base1.x)) << " " << base1.y << " ";
}
~Derived() {}
private:
base base1;
};
int main() {
Derived objDev(32, 33);
return 0;
}
I have problem with understand it.
Because i think it should give output as "33 0" but gave "1 0" and also i write in some std::cout for controlling in constructor body, and saw x[3] is -33686019 after '''(*x++) = x; ''' part. How could it be possible? how *x++ can change x[3] and why is this value?
and also compiler give error. doesn't *x++ mean what is x point, increase it? so when after assign xx to (*x++) wouldn't it be 32+1=33?
please help

x = new int[4]; creates an array of 4 int and sets x to point to the beginning of them. Because x is going to change, let’s call this array A, which will not change.
Then x[0] refers to the first element of this array, x[1] is the second, x[2] is the third, and x[3] is the fourth. So far x[0] and A[0] are the same thing, and so are the pairs x[1] and A[1], x[2] and A[2], and x[3] and A[3].
(*x++) is grouped as ( * (x++) ). x++ does two things. It produces the value of x, and, as a side effect, it increments x. Since x++ produces the value of x, *(x++) is the int that x points to before the increment.
This means that (*x++) = xx; stores x in the first element of the array, but it changes x to point to the second element, which is A[1].
Once x points to the second element, then x[0] is A[1], x[1] is A[2], x[2] is A[3], and x[3] is beyond the end of the array. x[-1] would be A[0].
So, where the code sends (*(this->x)) to cout, it is sending A[1], which has 1 in it. That explains why you got output of “1”.
When you looked at x[3], you were looking beyond the array. What is there could be some other value the program has worked with, completely unrelated to what is in the array. But accessing an element beyond array bounds can cause various problems with programs other than just giving a wrong value.
In the destructor, delete[] x; is wrong because x has been changed and no longer has the original address of the array. You could use delete [] --x; or delete [] x-1; to recalculate the original address. However, if a program has some need to use a pointer into the middle of an array, it is more common to store the base address and never change it and create a separate pointer into the middle. That is usually less error prone and easier for other programmers to follow.

Related

Create a two 2d array of pointers based on the same data

I was trying create a 2d array of pointers based on other. Here is a base 2d array:
double **a = new double*[3];
a[0] = new double[3]{ 1, 2, 3 };
a[1] = new double[3]{ 4, 5, 6 };
a[2] = new double[3]{ 7, 8, 9 };
And I want create a 2x2 matrix which should look like this:
5,6
8,9
Finally, I was trying resolve the problem as follow:
double **b = &a[1];
b[0] = a[1];
b[1] = a[2];
Unfortunately, this code does not work as I expect. In addition, I would like to get access to data using negative indices eg. b[-1][-1] should return 1 value.
With:
double a0[] = { 1, 2, 3 };
double a1[] = { 4, 5, 6 };
double a2[] = { 7, 8, 9 };
double* b0[3] = {&a0[1], &a1[1], &a2[1]};
double** b = &b0[1];
you can access with negative index and do:
for (int i = -1; i != 2; ++i) {
for (int j = -1; j != 2; ++j) {
std::cout << b[i][j] << std::endl;
}
}
This approach cannot work. One property of this kind of 2d array is that &A[k+1] = &A[k]+1, but that relationship does not hold between your desired B[0] and B[1], because those are actually &A[1][1] and &A[2][1], which could be miles apart.
What your code actually does is:
double **b = &a[1]; // all right, b points to part of a[]
b[0] = a[1]; // this assignment does nothing, they're already equal
b[1] = a[2]; // this assignment does nothing, they're already equal
This might help you out some and get you on the right track.
#include <conio.h>
#include <iostream>
struct Vec3 {
union {
double d3[3];
struct {
double x;
double y;
double z;
};
};
double& operator[]( int idx );
};
double& Vec3::operator[]( int idx ) {
return d3[idx];
}
typedef Vec3 Row;
struct Matrix {
union {
Row r[3];
struct {
Row row1;
Row row2;
Row row3;
};
};
Row& operator[]( int idx );
};
Row& Matrix::operator[]( int idx ) {
return r[idx];
}
int main() {
Matrix m;
m.row1.x = 1;
m.row1.y = 2;
m.row1.z = 3;
m.row2.x = 4;
m.row2.y = 5;
m.row2.z = 6;
m.row3.x = 7;
m.row3.y = 8;
m.row3.z = 9;
for ( int i = 0; i < 3; i++ ) {
for ( int j = 0; j < 3; j++ ) {
m[i][j] += 10;
std::cout << m[i][j] << " ";
}
std::cout << std::endl;
}
std::cout << "Press any key to quit" << std::endl;
_getch();
return 0;
}
I did not add any error checking or bounds checking into the overloaded operator I just allowed the user to pass any value into it. This you would have to design to your specific needs. I'm just demonstrating an easy way to create a 2D Array or a Matrix like object using unions to have quick access to the subscript or bracket operator. I show a sample use of creating a 3x3 matrix with each value ranging from 1-9 then I use a double for loop to add 10 to each value then print out the new value within the array using the double brackets. This is all done on the stack which is better then using pointers and creating new memory for each place. If you need to use the heap then you could just assign this matrix class its own pointer and create it on the heap instead of every individual element. Another thing that can be done with this is if you need to use this for say int, float or some other data type you can easily template this class or structure.
As for indexing by a negative value; I have not heard of anyone doing so. This isn't to say that it can not be done, but from what I recall on how pointers & arrays behave with indexing according to their association with memory addressing they are 0 based index. This usually means that if we have a memory block a pointer to a double type variable, this usually means that each block of memory in most cases is 8 bytes wide. The very first element resides in the very first memory address location that is assigned to this variable for both the stack and the heap. If you try to use negative numbers which involve pointer arithmetic you begin to traverse memory that doesn't belong to this declared variable. To try and pull off what you are suggesting might require more than just basic C/C++ code can do, you might have to dive into asm to get something like this to work, especially if you want to avoid using if statements within the overloaded operators.

First item in an array is getting... replaced?

New C++ learner here.
I am trying to build a struct whose member variables are 2 dynamically allocated int arrays.
The arrays are filled by std::cin.
#include <iostream>
struct foo
{
int* x;
int* y;
};
// Everything from here goes into the main()
unsigned int numArray;
std::cin >> numArray;
int* m = new int[numArray];
int* n = new int[numArray];
for(int z = 0; z < numArray; z++)
{
std::cin >> m[z];
}
for(int z = 0; z < numArray; z++)
{
std::cin >> n[z];
}
foo* bar = new foo;
bar->x = m;
bar->y = n;
delete[] m;
delete[] n;
This should have created a struct foo named bar, with the member variables m (int array) and n (int array).
My questions start here:
Inputs:
5 // length of the array
1 2 3 4 5 // for array int* x
6 7 8 9 10 // for array int* y
When I try to print the results with std::cout, however...
for(int z = 0; z < 5; z++)
{
std::cout << (bar->x)[z] << " ";
}
std::cout << std::endl;
for(int z = 0; z < 5; z++)
{
std::cout << (bar->y)[z] << " ";
}
std::cout << std::endl;
I get this.
0 2 3 4 5
146890752 7 8 9 10
My guess is that either 1. I built the array wrong or 2. I'm accessing the array wrong (or maybe both?), but I have no idea what to do. The first item in array x always seems to be 0 while the first item in array y seems to be some random large number. What's going on?
You deleted those arrays with delete[] m; delete[] n; . Then the rest of your code goes on to access deleted memory which causes undefined behaviour.
Maybe you misunderstand bar->x = m;. After that line, the two pointers bar->x and m both point to the same array of ints. Then you delete[] that array, leaving both pointers pointing to the deleted array (technically, both pointers are indeterminate).
If you remove those delete statements then your code should work better.
NB. If you have further questions then update your post to include your exact code, instead of describing it (e.g. int main() { instead of "into the main").
By using the delete[] function, you "deallocated" the memory, but it doesn't necessarily rewrite the data immediately. Deleting just frees it up. It rewrites the first one, but it's a shallow copy, copied only by address. Though it might be a memory leak of unallocatable memory until the program terminates; that does happen sometimes.

confused about pointers

I just started learning c++ (I'm more of a java developer right now) and am having some confusion with using pointers... for example, the following code works
int main() {
int x = 5;
int * y;
y = &x; //note this line of code
*y = 10;
}
whereas this code does not work
int main() {
int x = 5;
int * y;
y = x;
*y = 10;
}
Can someone explain to me why getting the value "location" using y = &x works but as soon as I replace it with y = x it causes an error. If anyone knows of a good explanation on pointers please share the link :)
Thank you!
Let's see how this works with pointers.
int x = 5;
You're assigning the value 5 to x which is an int.
int *y;
You're declaring a pointer to an int.
y = &x;
Now, the address stored in y is the same as the address of x.
But, if you do this : y = x, you're assigning an integer (5 in that case) to a variable that holds addresses of integers.
Finally, you have to remember that :
& is the address-of operator, and can be read as "address of"
* is the indirection operator, and can be read as "value pointed to by"
Tutorial about pointers
a pointer is a variable that holds a memory location. In your instance, the variable "x" holds the value 5, where the variable y holds a location in memory. the "&" operator will enable you to use the location in memory of the "x" variable
cout >> x; //will give you an output of 5.
cout >> &x; //will give you an output of the memory location of the variable x.
y = &x;
cout >> y; //will give you an output of the memory location of the variable x.
y is a pointer to an int. x is an int. Therefore whenever you set y=x you are telling y that whenever it gets dereferenced, it should go looking at memory location 10 (or whatever x is at assignment time). And there probably isn't a memory allocation at 10. Or at least not what you are expecting. If you want to get the location of x, get a pointer to it with &x.
int main() {
int x = 5;
int * y;
y = &x; // <-- NOTE THE "&" WHICH MEANS GET REFERENCE
*y = 10;
}

Copying one structure to another and Effect of changing one on Another

#include<stdio.h>
#include<string.h>
struct node
{
int a;
char *p;
};
int main()
{
struct node X,Y;
char s[5] = "Adam";
char t[5] = "Jack";
X.a = 5;
X.p = s;
Y = X;
Y.a = 10;
strcpy(Y.p,t);
printf("%d %s\n",X.a,X.p);
printf("%d %s\n",Y.a,Y.p);
return 0;
}
In this Question , Structure X has "a=5" and "P pointing to Adam". and then this is copied to another structure Y. and changes are made to Y.
But when strcpy(Y.p,t) is done .
OUTPUT IS :
5 Jack
10 Jack
This change is supposed to be only in Y , but these changes are also reflected for X. How so ?
MY question is "How does changing one structure member have effect on another when they are copied " ?
You initialized Y as copy of X. That means it contains the same pointer in the p field - you didn't ever change that.
When you do the strcpy, you're writing the contents of t overtop of s.
You're lucky you picked two 4-letter names...
strcpy(Y.p,t);
Y.p value is the same as the value of s. So the above function call is actually the same as:
strcpy(s, t);
This is because the character pointer p of both structures X and Y points to the same memory location.
so strcpy changes the data for both X and Y

Assigning a 2D array (of pointers) to a variable in an object for access in C++?

I'm sorry if I didn't pick a descriptive or concise name. A lot of questions sound similar, but I haven't been able to find what I'm looking for. What I want to do is store a 2D array of pointers somewhere and assign a variable in some object to that array to be able to access it.
Here's some example code that has the same compile error I'm getting with a bigger project.
#include <iostream>
using namespace std;
struct X{
float n, * b[8][8];
X(){
n = 1;
b[1][5] = &n;
cout << *(b[1][5]) << endl;
}
void Set(float * c[8][8]){
b = c;
cout << *(b[1][5]) << endl;
}
};
main(){
float m, * a[8][8];
m = 2;
a[1][5] = &m;
X obj;
obj.Set(a);
}
What I want to happen in this code is that an X object starts with its own 2D array, whose value pointed to by b[1][5] should be printed as "1". Then the main method's 2D array, a, is passed to the object's Set() method and assigned to its array variable. The value pointed to by b[1][5] should then be printed as "2".
However, I can't figure out what type the Set() parameter, c, should be. I get
error: incompatible types in assignment of ‘float* (*)[8]’ to ‘float* [8][8]’
when I try to compile. As for why I want to do this, I'm trying to use an array of pointers to objects, not floats, but it's the same error.
Try this:
#include <iostream>
using namespace std;
struct X{
float n;
float* (*b)[8];
X(){
n = 1;
b = new float*[8][8];
b[1][5] = &n;
cout << *(b[1][5]) << endl;
}
void Set(float * c[8][8]){
delete[] b;
b = c;
cout << *(b[1][5]) << endl;
}
};
main(){
float m, * a[8][8];
m = 2;
a[1][5] = &m;
X obj;
obj.Set(a);
}
Here, X stores a pointer to a 1D array, which we are treating as a pointer to the first element of a 2D array - i.e. as just a 2D array.
In X's constructor, X allocates its own array with new and sets its pointer to point to that. When calling Set(), X deletes its own array, and sets its pointer to point to the array provided by the caller.
The only thing to watch out for is, if you call Set() again, that array will in turn be deleted (which will blow up if that array is a stack array, like in this case). So, it might be advisable to separate the line that does delete[] b into its own member function, and call it only when necessary.
Your problem with set is that you need to copy the array contents - just doing b=c can't do what you want.
void Set(float * c[8][8]){
for(unsigned int i=0; i<8; ++i) {
for(unsigned int j=0; j<8; ++j) {
b[i][j] = c[i][j];
}
}
cout << *(b[1][5]) << endl;
}
There are several bugs I think..
Firstly, in Set() function you have assigned an array name. But array name should not be used as a variable. You can solve this by making 2D array of pointer b as a pointer to 1D array of pointer like float * (*b)[8]...
Secondly, when you send the 2D array of pointer as argument of Set() function it is decaying into a pointer to 1D array of pointer i.e something like this float *(*a)[8]. so you have to make the formal argument of Set() function a pointer to 1D array of pointers like void Set(float * (*c)[8])...
And finally there is a thing your float variable m inside main is a local to main , so when control pass to Set() function I think the compiler cant find the value(may be deallocated) in the m...so it outputs undefined or give run time error..you can solve this by making m a static version. i.e by declaring static float m...
In total make your code like following :
#include <iostream>
using namespace std;
struct X{
float n, *(*b)[8];
X(){
n = 1;
b[1][5] = &n;
cout << *(b[1][5]) << endl;
}
void Set(float * (*c)[8]){
b = c;
cout << *(b[1][5]) << endl;
}
};
main(){
float * a[8][8];
static float m;
m = 2;
a[1][5] = &m;
X obj;
obj.Set(a);
}
This will output correctly :)