0

For the class dataCard here's an implementation of its constructor (here name is a public member of type const char*:

dataCard::dataCard(const char* fname) {
  ...
  name = fname;
  ...
}

And copy constructor:

dataCard::datCard(const dataCard& rhs) {
  ...
  name = rhs.name;
  ...
}

When later in main I initialize an object of type dataCard as follows

dataCard card("myCard");

and try to print its name

cout << card.name;

I obviously get

myCard

However when I put this object in a vector

vector<dataCard> cards;
cards.push_back(myCard);

and try to print the name of the card this way

cout << cards[0].name;

the name is not represented correctly. I get some strange sequence of unknown symbols instead of the expected myName.

I suspect there's a problem with the copy constructor and the type const char*, since I have another member of type char in my class, which is represented properly when calling it after putting the element into the vector. Where does the problem lie?

Dmitry Kazakov
  • 165
  • 1
  • 9
  • 2
    You should be using `std::string` instead of C strings. Should be no problem then. – crashmstr Nov 21 '14 at 13:41
  • Do you have a move constructor in addition to the copy constructor? If so, does it handle name correctly? – dlf Nov 21 '14 at 13:42
  • @crashmstr I have to use `const char*` since it is used in API methods I use – Dmitry Kazakov Nov 21 '14 at 13:43
  • @dlf no I don't have a move constructor. As I mentioned, I have some more members that get initialized properly using the current implementation of the copy constructor. The only problem is with this `name` field of the type `const char*`. – Dmitry Kazakov Nov 21 '14 at 13:45
  • You didn't copy the c-string in your copy constructor, you only copied a pointer to it. Presumably the c-string then went out of scope? – Galik Nov 21 '14 at 13:46
  • 1
    "I suspect there's a problem with the copy constructor" - yes, simply copying the pointer is the wrong thing to do. Both objects end up sharing the same underlying array. Presumably, the destructor of one object is deleting the array, leaving the other with a dangling pointer. Read about the [Rule of Three](http://stackoverflow.com/questions/4172722), and don't try to implement copy/move semantics yourself unless you're writing your own resource management class (in which case, be very careful). In this case, just use `std::string` to handle all the memory shenanigans for you. – Mike Seymour Nov 21 '14 at 13:46
  • I'd suggest doing this in the debugger: Set a breakpoint when the dataCard is constructed and note the numerical value of the address `name` points to. Set another breakpoint when the junk is output and check the address again. Are they different? Something isn't copying correctly, or is changing name after the copy. Are they the same? Something is corrupting memory. – dlf Nov 21 '14 at 13:46
  • 5
    @DmitryKazakov You should use `std::string` anyway. You can use `c_str()` to pass a `const char*` to your API. – Sambuca Nov 21 '14 at 13:46
  • @MikeSeymour Of course, `delete`ing name would be a very bad idea here anyway since it was not allocated with `new`. – dlf Nov 21 '14 at 13:48
  • @DmitryKazakov *Does* your destructor `delete name`? If not, the question is (probably) not a duplicate. – dlf Nov 21 '14 at 13:51
  • @dlf: True, I didn't notice that detail. So the direct problem is hopefully somewhere else; but the underlying problem of a sketchy ownership model is still best solved using correctly copyable types like `string`. – Mike Seymour Nov 21 '14 at 13:52
  • @Sambuca that is how I will do it, thanks – Dmitry Kazakov Nov 21 '14 at 13:52

0 Answers0