10

I've got a class definition similar to the following:

class UUID
{
  public:
    // Using implicit copy assignment operator

  private:
    unsigned char buffer[16];
};

I've just had a unit test fail on me that was verifying that copy assignment worked properly. To my surprise, one byte in the middle of the buffer[] array was copied incorrectly.

My understanding is that the default copy assignment operator performs memberwise copy, and that for array members (not pointer-to-array members) that entails elementwise copy of the array. Am I mistaken?

My gut feeling here is that I've been bitten by a dangling pointer somewhere that has stomped on the middle of my array. But, I'm seeing this repeatably when, e.g. I copy a vector of these objects into another vector.

Anybody care to tell me where I've gone wrong?

Edit:

To expand on this a bit, the class is not a POD type--it derives from a few abstract base classes and thus has a virtual destructor. However, the array is the only data member, and the usage which broke in the unit test was this:

const int n = 100;

std::vector<UUID> src, dst;
src.reserve(n);
dst.resize(n);

for (int i = 0; i < n; ++i) {
  UUID id;
  src.push_back(id);
}

for (int i = 0; i < n; ++i) {
  dst[i] = src[i];
}

bool good = true;
for (int i = 0; i < n; ++i) {
  const bool thisGood = (dst[i] == src[i]);

  std::cout << "i = " << i << " -> src = '" << src[i]
            << "', dst = '" << dst[i] << "', src == dst ? "
            << thisGood << '\n';

  good = (good && thisGood);
}
Drew Hall
  • 28,429
  • 12
  • 61
  • 81
  • How did you find "one byte in the middle of the buffer[] array was copied incorrectly." with the test case shown? Is there any particular entry(out of 100) that is getting corrupted? – Chubsdad Sep 10 '10 at 02:08
  • @Chubsdad: The UUID class has a stream inserter overloaded that dumps the contents of the member array. For this test case, all 100 elements of the vector have their buffer[9] byte corrupted, to exactly the same value. – Drew Hall Sep 10 '10 at 02:47
  • Ok. Is it possible to show the overloaded operator==? – Chubsdad Sep 10 '10 at 03:19
  • @Chubsdad: It's just an elementwise comparison as you'd expect--it works correctly and confirms what I've seen both in the output text and via direct inspection in the debugger. Also, the code has worked fine thus far with MinGW (4.5.4) and GCC on Linux--it only seems to be broken on MSVC 2005. I think I must have memory corruption somewhere.... – Drew Hall Sep 10 '10 at 07:27

1 Answers1

13

My understanding is that the default copy assignment operator performs memberwise copy, and that for array members (not pointer-to-array members) that entailed elementwise copy of the array.

Yes. This is correct.

Your problem is not with the copy assignment operator (unless you have found some unusual compiler bug, which is unlikely).

James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Thanks! I think I'm going to need it. BTW, I added some extra text/test case code in an edit. I don't think it changes anything but thought I'd bring it to your attention anyway. – Drew Hall Sep 09 '10 at 23:39
  • I had a similar issue, which actually leads to some known bugs of the g++ compiler. http://stackoverflow.com/questions/16128882/gdb-debug-issue-phantom-value-seen-in-gdb-debug-steps – zinking Apr 22 '13 at 05:37