1

Is my assumption, that in following example, memory referenced by b will be deallocated once instance of A goes out of scope at end of func(), correct?

class A{
public:
   A() {
        b = std::shared_ptr<char>(new char[100] { 0 } );
   }
   char* b;
}

void func {
   A a;
}
JamesWebbTelescopeAlien
  • 3,547
  • 2
  • 30
  • 51
  • I would double check that using `shared_ptr` with an array in that fashion is correct. Maybe it is, I'm not sure. – Neil Kirk Oct 30 '15 at 03:34
  • @NeilKirk, `shared_ptr` has been proposed for C++17. I thought I saw somewhere that it was accepted, but I could be wrong. – chris Oct 30 '15 at 03:51
  • @NeilKirk: According to [this, definitely not safe.](https://stackoverflow.com/questions/3266443/can-you-use-a-shared-ptr-for-raii-of-c-style-arrays) – ShadowRanger Oct 30 '15 at 04:01

2 Answers2

3

No, not correct. b is of type char * and you assign to it a shared_ptr<char>. You should get a compilation error.

Furthermore, the constructor is private, another compilation error.

And how do you access b in func()? It is private in A.

Obviously your exercise is incomplete... so I just go from what you provided.

Also I suggest to use unique_ptr in case you can say it is a unique ownership (which it appears to be in my opinion).

This compiles:

#include <memory>
#include <iostream>

class A {
public:

    A() {
        std::cout << "A created with unique pointer" << std::endl;
        b = std::unique_ptr<char>(new char[100] {
            0
        });
    }

    ~A() {
        std::cout << "A destroyed" << std::endl;
    }

private:
    std::unique_ptr<char> b;
};

void func() {
    A a;
}

int main() {
    std::cout << "Call func()" << std::endl;
    func();
    std::cout << "func() called" << std::endl;
    return 0;
}

And at the end of func() A is destroyed and with it the unique_ptr.

However, ask yourself if you really need to use pointer? In your case an automatic variable should be just fine; it does the same (i.e. being destroyed when func() exits.

Ely
  • 10,860
  • 4
  • 43
  • 64
2

You're assigning to a char* member, so I'm pretty sure the shared_ptr is cleaned up as soon as the assignment completes (because it wasn't stored to another shared_ptr that would maintain the reference count).

If you want to use shared_ptrs, you have to use them consistently; a raw pointer class member can't manage anything for you. The pointer is still initialized to where the memory was allocated, but it's not allocated anymore; accessing it even a line later in the constructor would be undefined behavior/a use-after-free bug.

In any event, not safe because default shared_ptr uses delete, not delete[]. Is there some reason a std::shared_ptr<std::array<char, 100>> couldn't be used?

ShadowRanger
  • 143,180
  • 12
  • 188
  • 271