lutzky
lutzky

Reputation: 618

Strange segfault when compiling with -O3

The following code compiles and works correctly on g++ 4.7.2-5 on Debian 7.

#include <iostream>
#include <string.h>

using namespace std;

class mystring {
  char * buf;
  static char * dupbuf(const char * buf) {
    char * result = new char[strlen(buf) + 1];
    strcpy(result, buf);
    return result;
  }

  public:
    mystring(const char * o)
    : buf(dupbuf(o)) {}

    ~mystring() { delete[] buf; }
    mystring(const mystring &) = delete;
    mystring & operator=(const mystring&) = delete;

    void write(ostream & o) const {
      if (!buf) { exit(1); } // remove me
      o << buf;
    }
};

ostream & operator <<(ostream & o, const mystring & ms) {
  ms.write(o);
};

int main() {
    mystring m("hello");
    cout << m << endl;
    return 0;
}

...unless you compile with -O2 or above. Then it segfaults, and valgrind claims an invalid read from 0x0. I'm guessing there's some stack corruption, but for the life of me I can't find it.

Interestingly, removing the line marked "remove me" makes the problem disappear. So does adding an endl to write. Any ideas?

Upvotes: 1

Views: 154

Answers (1)

Ulrich Eckhardt
Ulrich Eckhardt

Reputation: 17415

ostream & operator <<(ostream & o, const mystring & ms) {
  ms.write(o);
};

This causes undefined behaviour because it doesn't return anything. Also, the empty declaration at namespace level (";") is completely unnecessary (and used to be illegal in older C++ standards).

Upvotes: 9

Related Questions