type &var = *ptr VS type var = *ptr

huangapple go评论74阅读模式
英文:

type &var = *ptr VS type var = *ptr

问题

Let foo be:

class Foo {
public:
	Foo(int a) {
		aa = a;
		cout << "foo built. " << aa << endl;
	}
	~Foo() {
		cout << "foo DIED. " << aa << endl;
	}

	int aa;
};

Also, assume we have:

Foo* func1(){
	Foo* foo = new Foo(1);
	return foo;
}

Now, running this:

{ // <---- we have braces
	Foo obj = *func1();
}

yields: "foo DIED"

but running:

{
    Foo &obj = *func1();
}

does not release foo's instance.

Could you please clarify what's happening here?

英文:

Let foo be:

class Foo {
public:
	Foo(int a) {
		aa = a;
		cout << "foo built. " << aa << endl;
	}
	~Foo() {
		cout << "foo DIED. " << aa << endl;
	}

	int aa;
};

Also, assume we have:

Foo* func1(){
	Foo* foo = new Foo(1);
	return foo;
}

Now, running this:

{ // <---- we have braces
	Foo obj = *func1();
}

yields: "foo DIED"

but running:

{
    Foo &obj = *func1();
}

does not release foo's instance.

Could you please clarify what's happening here?

答案1

得分: 2

func1 分配了一个 Foo 并返回指向它的指针。迟早需要有人手动deleteFoo以释放它使用的资源。因为*func1()在制作指针的副本之前对指针进行解引用,所以指针丢失。没有了指针,对象可能永远丢失,当你不再需要它时,就无法进行delete

Foo obj = *func1(); 导致创建了两个 Foo。一个是在 func1 中动态分配的,另一个是自动分配的名为 objFoo,它是从 func1 中的 Foo 复制而来的。当obj超出范围时,你看到的是obj的销毁。func1中的Foo已经丢失。这称为内存泄漏。这段代码无法修复。它是有问题的,即使看起来似乎工作正常。

Foo &obj = *func1(); 创建了一个 Foo,即来自 func1 的一个,obj只是对它的引用。当引用超出范围时,什么都不会发生。你不能再引用对象为obj,引用不再存在,但对象仍然存在于内存中并已泄漏。但在这种情况下,当你仍然有obj引用时,你可以delete &obj;并释放它。

现在你可以看到对象被释放。

总之,你必须始终保持对动态分配对象的活动引用或指针,直到手动释放它。

英文:

func1 allocates a Foo and returns a pointer to it. Sooner or later someone must manually delete that Foo to free up the resources it uses. Because *func1() dereferences the pointer before a copy of the pointer is made, the pointer is lost. Without the pointer, the object could be lost forever, preventing you from deleteing it when you no longer need it.

Foo obj = *func1(); resulted in the creation of two Foos. The one dynamically allocated in func1 and another automatically allocated Foo named obj that is a copy of the Foo from func1. It is the death of obj when it goes out of scope that you are seeing. The Foo from func1 has been lost. You have what's called a memory leak. This code cannot be fixed. It is broken, even though it's the one that looked like it worked.

Foo &obj = *func1(); creates one Foo, the one from func1, and obj merely references it. When the reference goes out of scope nothing happens. You can't refer to the object as obj anymore, the reference is no more, but the object still exists in memory and has been leaked. But in this case while you still have obj referencing it, you can delete &obj; and free it.

{
    Foo &obj = *func1();
    delete &obj; // get address of referenced object, then delete it.
}

Now you can see the object being freed.

Long-and-short: You always have to keep a live reference or pointer to a dynamically allocated object until you manually release it.

huangapple
  • 本文由 发表于 2023年3月31日 04:06:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75892559.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定