C++ public constructor address
After writing the code below:
#include <iostream>
using namespace std;
typedef struct Node {
int value;
Node(int index) {
value = index;
}
} Node;
int main() {
Node* arr[10];
for(int i = 0; i < 10; i++) {
arr[i] = &Node(i);
}
for(int i = 0; i < 10; i++)
cout << arr[i]->value << endl;
}
I saw that the code prints only 9's instead of all the numbers from 0 to 9 it was supposed to.
After debugging the code i saw that address of arr[i] for each i are the same, and Node(i) have freed the space for arr[i] only once, and after that the only thing it is value = index
wi开发者_JAVA百科thout freeing any other space. Why?
This line: arr[i] = &Node(i);
is storing a pointer to a temporary object. Node(i)
creates a temporary object that can be destructed at the end of the statement, at which point all references to it become invalid meaning the results of any code that dereferences arr[i]
will be undefined. The reason in this case you get all 9's is because the compiler is optimizing the code -- since only 1 temporary Node(i)
is being created at a time, the compiler is just reusing that memory each time through the loop.
To fix the problem, allocate memory off the heap for each object: arr[i] = new Node(i);
. Then when you are done using them you will also need to remember to delete each one:
for (int i=0; i < 10; ++i) {
delete arr[i];
}
If you want to investigate farther, try adding some code to your Node
class to see what's happening: for example print out the address of this
in your constructor, and/or create a destructor that just prints a message out so you can see it being called.
To create new objects, use new Node(i)
otherwise you are creating temporary objects on the stack which is why they are all the same.
Remember to call delete on each object that you get back from new.
&Node(i)
This expression creates a temporary variable and returns its address. The temporary is then destroyed, and the next time the expression is evaluated, another temporary is created in the same place — hence the identical addresses.
You should probably eliminate the use of pointers, and introduce a default value for Node.
#include <iostream>
using namespace std;
typedef struct Node {
int value;
Node(int index) {
value = index;
}
Node() : value( 0 ) {} // allow default construction
} Node;
int main() {
Node arr[10]; // default-construct array values
for(int i = 0; i < 10; i++) {
arr[i] = Node(i);
}
for(int i = 0; i < 10; i++)
cout << arr[i].value << endl;
}
Do not use new Node
for each object individually. Always use a container object to manage a group of objects with similar semantics. You might use std::vector
here, or std::array
if you have it. The overhead introduced by std::vector
will be less than that introduced by new
.
精彩评论