-2

My code is just like below:

class CDemo {
public:
    CDemo()
        : str(NULL){

          };
    ~CDemo() {
        if (str)
            delete[] str;
    };
    char* str;
};

void testVector() {
    CDemo c;
    c.str = new char[32];
    strcpy(c.str, "abcdef");
    vector<CDemo>* v = new vector<CDemo>();
    v->push_back(c);
    delete (v);
    return;
}

I know this is a code which will report a run-time error because I didn't explicitly define a copy constructor, so ,when testVector returned , the member field str will be freed twice, thus reporting an error.But what make me confused , is that when I debug to the line: delete(v), the visual studio shortcut is as below: enter image description here

I think the function push_back will lead to the call of the default copy constructor of object c, so, after push_back returned , the element of vector v should be a different object from c, but from the debug watch, I find they are the same address:0x00318100. Does it prove that they are actually the same object? Anyone can explain this?

NetVipeC
  • 4,402
  • 1
  • 17
  • 19
wuchang
  • 3,003
  • 8
  • 42
  • 66

3 Answers3

1

It does push a copy of the CDemo object.

However, both copies contain the same value of their str pointers. That's what you're looking at in the debugger, and that's why both try to delete the same array.

To fix the double-deletion, either

  • Use std::string to correctly manage memory for you; or
  • Carefully implement a copy-constructor and copy-assignment operator to correctly copy the string contents, not the pointer, per the Rule of Three.

Unless you're teaching yourself how to manage dynamic memory, or have very special requirements, just use std::string. And in general, don't use new unless you really need to - in particular, there's no reason to dynamically allocate the vector.

Community
  • 1
  • 1
Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
0

You're looking at the char* address which gets copied "as it is" once set and not at the address of an object.

The address of the pointers will probably be different (you can verify that by enabling the code disassembly mode and looking at the pointers involved and/or by looking at the stack and memory dump) but they do point at the same location.

Marco A.
  • 43,032
  • 26
  • 132
  • 246
0

"c" might be stack allocated:

CDemo c ;

But you pushed a heap allocated pointer into "c":

c.str=new char[32];

So you could add another constructor that makes a own heap allocated copy of the content:

CDemo(const char* src) :str(new char[strlen(src)+1]) {
    strcpy(str, src);
};

and than use it this way:

vector<CDemo> v;
v.push_back(new CDemo("abcdef"));