-2

Here are my thoughts of C++ Memeory management, please feel free to comment.

Memory can be allocated in stack or heap.

Rule 1:

If two nested stacks need to share data, use RAII allocating memory in stack, like below:

func1() {
    Resource res;  // res will be destructed once func1 returns
    func2( &res );
}  

Rule 2:

If two parallel stacks need to share data (not class member fields), memory must be allocated in heap, use Smart Points or GC. For example:

func() {
    shared_ptr<Resource> res = func1();   // returned a shared ptr to a memory allocated in func1
    func2( res );
}

Am I correct?

Zach
  • 5,715
  • 12
  • 47
  • 62
  • 1
    What is your question exactly? And with respect to what, the standard? Because strictly speaking C++ has no concept of a "stack" or "heap", at least not when discussing the memory model. – user657267 Apr 17 '15 at 02:06
  • RAII, shared_pointer are used when polymorphism is involved – billz Apr 17 '15 at 02:12

2 Answers2

0

My opinion is that you are right, (parallel stacks means multithread I suppose)

Also is ok to use scoped_ptr(boost) or unique_ptr(c++11) in your first case. In that case object is allocate in memory heap instead of stack. and RAII also free that memory after the scope is finished.

shared_ptr is a reference count mechanism, so if other object keep the shared_ptr(in your case:func2), and didn't release it after your func scope finished, the object shared_ptr is still available.

Gohan
  • 2,422
  • 2
  • 26
  • 45
  • The example for case 2 is single-threaded, so I think you're reading too much into this. – MSalters Apr 17 '15 at 09:02
  • @MSalters I don't really understand the parallel stacks, because single thread could only have one stack at a time. – Gohan Apr 17 '15 at 12:19
  • Gohan, yes a single thread only have one stack. Here, I treat a function as one stack. – Zach Apr 20 '15 at 02:15
  • I now understand you more, in your case 2, `func1` allocate a object, and return. `Resource res = func1()` when `Resource` is a big object not a Resource handle, this approach is consider not effective, better to use scoped_ptr/shared_ptr to do so. (c++ 11 has a move assign operator, I think it could help you to use `Resource res = func1()` like approach, having equally performance like xxx_ptr approach) – Gohan May 05 '15 at 02:50
0

No. Your example 2 is better written as just

void func() {
    Resource res = func1();   // func1 returns a Resource
    func2( res ); // func2 uses that Resource.
}
MSalters
  • 173,980
  • 10
  • 155
  • 350
  • I disagree with you. The 'res' is destroyed once it leaves func1(), so must return a raw pointer (manually delete after func2()) or a smart_pointer. If you mean 'res' holds a pointer to a block of memory inside, then 'res' itself is a smart pointer. – Zach Apr 18 '15 at 02:49
  • @Zach: Wrong. `res` doesn't even _exist_ in `func1` so it can't be destroyed. But just try it with `std::string` as a resource: From `func1`, return `std::string("Hi")`, and see that the code above will pass Hi to `func2`. – MSalters Apr 18 '15 at 14:53
  • std::string is ref counted. See: http://stackoverflow.com/questions/12520192/is-stdstring-refcounted-in-gcc-4-x-c11 – Zach Apr 20 '15 at 02:11
  • @Zach: Note that the linked question talks specifically about GCC, **and** notes that the GCC implementation is in fact wrong. Even so, that would not change anything. `std::string` is not a smart pointer, as it lacks both `operator*` and `operator->`. – MSalters Apr 20 '15 at 10:43
  • MSalters: in your code, func1() returns Resource, can you show the inside code of func1()? how does it allocate memory? – Zach Apr 21 '15 at 02:01
  • @Zach: Taking `std::string` as an example, like this: `std::string func1() { return "hi"; }`. As you can see, no mention of `res` nor a mention of `new`. Using RAII, the resource class (`std::string`) manages memory. See `std::allocator` for all the details – MSalters Apr 21 '15 at 07:04
  • MSalters: 'std::string' may be a little special, because "hi" may not be allocated in stack. Can you use a class of your own? – Zach Apr 21 '15 at 08:18
  • @Zach: I've got no idea what you mean with that "not on stack" argument. But exactly the same principle applies to `std::map` for instance, or `std::complex`. Many, many classes in C++ have value behavior. – MSalters Apr 21 '15 at 19:50
  • in `std::string func1() { return "hi"; }. ` , do you mean the two chars in the string are copied when return? What if it is a very long string, are all chars in the string be copied too? – Zach Apr 22 '15 at 02:26
  • Well, the string _literal_ is a constant, and the `std::string` is modifiable, so you by necessity have that one copy - but that's a detail of the example initialization. After that, the string is _moved_ out, not copied. – MSalters Apr 22 '15 at 08:33