我需要在循环中创建对象指针,但我正在努力创建唯一指针。这是我的代码:
class DatClass{
public:
int m;
DatClass(int i):m(i){}
};
class OtherClass{
public:
DatClass* dc;
};
void Test(std::vector<OtherClass> v){
std::vector<OtherClass>::iterator it;
int i = 1;
for(it = v.begin(); it != v.end(); it++){
DatClass dc = DatClass(i);
std::cout << &dc << std::endl;
it->dc = &dc;
i++;
}
}
int main(){
std::vector<OtherClass> v;
v.push_back(OtherClass());
v.push_back(OtherClass());
v.push_back(OtherClass());
Test(v);
}
这并没有给我独特的指示。输出显示:
0xbf94d72c
0xbf94d72c
0xbf94d72c
我是否需要使用new才能获得独特的指针?如果是这样,我会把相应的删除放在哪里? 谢谢!
答案 0 :(得分:3)
是的,您应该使用new
来获取唯一地址。
delete
应该在循环完成时 - 否则(删除在同一循环内) - 操作系统可以再次给你相同的地址。
(或者确切地说 - 当你完成了在这个地址中分配的对象时)
您的代码中发生的是您使用自动分配的内存。这个内存通常分配在堆栈上 - 在每次迭代中 - 相同的内存被重用于变量 - 因此它为您提供相同的地址。
答案 1 :(得分:2)
DatClass dc = DatClass(i);
在堆栈上创建类的实例。它的地址在循环中保持不变,这就是输出相同的原因。
您可能想要执行以下操作:
void Test(const std::vector<OtherClass>& v){
std::vector<OtherClass>::iterator it;
for(it = v.begin(); it != v.end(); it++){
const DatClass& dc = *it;
std::cout << &dc << std::endl;
}
}
答案 2 :(得分:1)
Test
内循环的每次迭代都会在堆栈上创建一个新的DatClass
实例并打印其地址。在下一次迭代之前,此对象的生命周期结束,这使编译器能够在下一次迭代中重用相同的内存。
这就是为什么你总是看到相同的地址(当然这只是因为标准特别允许编译器这样做)。
如果要查看对象的不同地址,则应该在循环外部的函数范围内分配所有这些地址(在这种情况下,它们将驻留在堆栈上但位于不同的地址),或者在堆上分配它们。
当然,显而易见的是vector
本身包含的内容没有任何区别,因为这只会影响循环的迭代次数。如果更改代码以打印vector
内实际对象的地址,您还会看到不同的地址。
答案 3 :(得分:0)
简短,你试图动态地这样做。这意味着nu不在堆栈上。因此,只有在您需要或不在程序启动时使用它时才会分配更多内存。
所以int a = 5; <<< stack
和new int* b = 55
(完成使用后,你必须释放delete b;
的内存或稍后会出现的错误的分段错误错误。);
`cout<< &b;` prints the value stored at the pointer ` 55`
`cout<< *b` prints the pointers value in memory `#1234` i think this is called offset
我要求你解决这个基本问题: http://www.cplusplus.com/doc/tutorial/
答案 4 :(得分:0)
我认为您可能正在尝试将 new DatClass分配给OtherClass,而是指定一个 auto (在堆栈上)DatClass,它在每个循环迭代,因为它是一个自动对象(并且编译器在堆栈上重用它的地址,这就是为什么你总是看到相同的地址)
我宁愿换掉这个:
for(it = v.begin(); it != v.end(); it++){
DatClass dc = DatClass(i); // auto object destroyed and address reused
std::cout << &dc << std::endl;
it->dc = &dc;
用这个:
for(it = v.begin(); it != v.end(); it++){
DatClass *dc = new DatClass(i); // new object on heap
std::cout << dc << std::endl;
it->dc = dc;
所以现在要创建 new DatClass对象以分配给OtherClass对象。
(此外,你还应该在delete
那些新的DatClass对象,以避免资源泄漏)
答案 5 :(得分:-1)
您打印dc
的地址。 dc
每次都在同一位置的堆栈中。这就是为什么你每次都得到相同的地址。
您可以将循环更改为:
for (auto it = v.begin(); it != v.end(); ++it){
OtherClass *oc = &(*it);
std::cout << oc << std::endl;
}
,它为您提供v