如何在堆栈和堆对象之间转换
示例:
Class *_obj1;
Class *_obj2;
void doThis(Class *obj) {}
void create() {
Class *obj1 = new Class();
Class obj2;
doThis(obj1);
doThis(&obj2);
_obj1 = obj1;
_obj2 = &obj2;
}
int main (int argc, const char * argv[]) {
create();
_obj1->doSomething();
_obj2->doSomething();
return 0;
}
这将创建 2 个对象,创建指向它们的指针,然后 main() 对每个对象调用一个方法。 Class 对象创建一个 char* 并存储 C 字符串“Hello!”在其中; ~Class() 释放器释放内存。 doSomething() 方法使用 printf() 打印出“buff: %s”。够简单的。现在,如果我们运行它,我们会得到:
解除分配
浅黄:你好!
浅黄色:ø_ˇ
显然,堆栈对象在这里不起作用 - 很明显,当函数退出时,指针 _obj2 指向堆栈中的某个位置。这就是为什么我在上一个问题中使用堆对象,人们告诉我这是“愚蠢的”。
所以,第一个问题是:如果如何将堆栈对象(obj2)转换为堆对象,以便在 create() 退出后它不会被释放?我想要一个直接的答案,而不是一个傲慢的“你正如许多人所做的那样,“做错了”。因为在这种情况下堆栈对象无法工作,所以堆对象似乎是唯一的方法。编辑:此外,转换回堆栈对象也很有用。
第二个问题:堆对象“错误”的具体示例是使用 new
运算符创建一个新的 vector
。 如果动态分配 STL 对象是错误的,那么正确的方法是什么? 显然,如果您将它们创建为堆栈对象,则会失败,因为它们会立即释放,但我被告知(再次,由一个非常高级别成员),动态分配它们可能会损坏堆。那么正确的做法是什么呢?
Example:
Class *_obj1;
Class *_obj2;
void doThis(Class *obj) {}
void create() {
Class *obj1 = new Class();
Class obj2;
doThis(obj1);
doThis(&obj2);
_obj1 = obj1;
_obj2 = &obj2;
}
int main (int argc, const char * argv[]) {
create();
_obj1->doSomething();
_obj2->doSomething();
return 0;
}
This creates 2 objects, creates pointers to them, then main() calls a method on each. The Class object creates a char* and stores the C string "Hello!" in it; the ~Class() deallocator frees the memory. The doSomething() method prints out "buff: %s" using printf(). Simple enough. Now if we run it we get this:
Dealloc
Buff: Hello!
Buff: ¯ø_ˇ
Obviously the stack object does not work here - it's obvious that when the function exits the pointer _obj2 is pointing at a location in the stack. This is why I used heap objects in my previous question, which people told me was "stupid".
So, the first question is: if how can I convert the stack object (obj2) to a heap object so it's not deallocated after create() exits? I want a straight answer, not an arrogant "you're doing it wrong" as so many have done. Because in this case stack objects cannot work so heap objects seem to be the only way. EDIT: Also, converting back to a stack object would be useful as well.
The second question: the specific example of heap objects being "wrong" was creating a new vector<string>*
using the new
operator. If dynamically allocating STL objects is wrong, then what's the right way? Obviously if you create them as stack objects it fails because they're immediately deallocated, but I've been told (again, by a very high-ranking member) that dynamically allocating them can corrupt the heap. So what's the right way to do it?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
直接的答案是:你不能在堆栈和堆之间“转换”对象。你可以创建位于另一个空间的对象的副本,就像其他空间一样已经指出了,但仅此而已。
动态分配 STL 对象本身不会损坏堆。 (不知道您可能在哪里听说过。)
如果您想在创建它的函数之外使用堆栈分配的 STL 对象,您不能,因为其中的堆栈空间对象所在的对象仅在创建它的函数内有效。
但是,您可以返回对象的副本:
不过,正如我所说,这将返回对象的副本,而不是原始对象本身 - 这是不可能的,因为包含该对象的堆栈在函数返回。
另一种选择是让调用者传入指向函数操作的对象的引用/指针,如果这对您的特定场景有意义的话:
如您所见,您仍然分配了堆栈上的所有内容,并且避免了(有时是必然的)依赖复制构造函数返回对象副本的开销。
The straight answer is: You can't "convert" an object between the stack and heap. You can create a copy of the object that lives in the other space, as others have pointed out, but that's it.
Dynamically allocating STL objects will not on its own corrupt the heap. (No idea where you might have heard that.)
If you want to use a stack-allocated STL object outside of the function that you created it in, you can't, since the stack space in which the object resides is only valid inside the function that created it.
You can, however, return a copy of the object:
As I said, though, this will return a copy of the object, not the original object itself -- that would be impossible, since the stack that contains the object is unwound after the function returns.
One other option is to have the caller pass in a reference / pointer to the object that your function manipulates, if this makes sense for your particular scenario:
As you can see, you've still allocated everything on the stack, and you avoid the (sometimes consequential) overhead of relying on the copy-constructor to return a copy of the object.
这一行:
更改为:
这是您能得到的最直接的答案。显然你是 C++ 新手,所以我确信这不会按预期工作,因为你可能在类“Class”的定义中犯了一些错误(顺便说一句,名字很糟糕)。
为什么要动态分配向量。只需在本地创建它即可。
使用new/delete就是像C一样使用C++。你需要阅读的是智能指针。这些对象控制对象的生命周期,并在超出范围时自动删除对象。
这里 x 是一个智能指针(类型为 auto_ptr),当它超出范围时,对象将被删除。但是您可以将 auto_ptr 返回给调用函数,它将安全地从函数中转移出来。它实际上比这复杂得多,你需要一本书。
当超出范围时就会释放。
如果你做错了。鉴于你的知识,这很有可能。但由于您没有提供类的定义,因此很难验证。
This line:
Change to:
Thats as straight an answer as you can get. Obviously you are new to C++, So I am sure this will nto work as intended because you have probably made a couple of mistakes in the defintion of the class "Class" (by the way terrible name).
Why do you dynamically allocate the vector. Just create it locally.
Using new/delete is using C++ like C. What you need to read up on is smart pointers. These are obejcts that control the lifespan of the object and automatically delete the object when they go out of scope.
Here x is a smart pointer (of type auto_ptr) when it goes out of scope the object will be deleted. But you can return an auto_ptr to the calling function and it will be safely transfered out of the function. Its actually a lot more complicated than that and you need a book.
Its de'allocated when it goes out of scope.
If you do it incorrectly. Which given your knowledge is very likely. But hard to verify since you have not provided the definition of Class.
您必须复制构造一个新的堆对象 (
Class * foo = new Class(obj2)
) 或将堆栈对象分配给堆对象 (*obj1 = obj2
) )。You have to either copy-construct a new heap object (
Class * foo = new Class(obj2)
) or assign the stack object to a heap object (*obj1 = obj2
).唯一的方法是复制对象。
将声明更改为:
Class _obj2;
并赋值:
_obj2 = obj2;
the only way is to copy object.
Change declaration to:
Class _obj2;
and assign:
_obj2 = obj2;
获取堆栈变量的地址不会神奇地将其传输到堆中。您需要为您的类编写适当的复制构造函数并使用
_obj2 = new Class(obj2);
。至于STL容器,它们无论如何都在堆上分配数据,为什么要在堆上分配容器本身呢?将它们放在一个范围内,只要您需要它们,它们就能保持活力。
Taking the address of a stack variable won't magically transfer it into heap. You need to write a proper copy-constructor for your class and use
_obj2 = new Class(obj2);
.As for STL containers, they allocate their data on the heap anyway, why would you want to allocate container itself on the heap? Put them in a scope that will keep them alive as long as you need them.
您的堆栈对象是在 create 函数内创建的,一旦超出该函数的范围就会被释放。指针无效。
您可以将
Class* obj2
更改为Class obj2
并通过obj2 = obj2;
分配(这意味着复制)对象Your stack object is created inside the create function and is deallocated as soon you get out of scope of the function. The pointer is invalid.
You could change
Class* obj2
toClass obj2
and the assign (which means copy) the object byobj2 = obj2;
我认为您真的想问“如何返回在函数内创建的对象?”有几种有效的方法:
I think you're really trying to ask "How can I return an object created inside my function?" There are several valid ways: