2

I was working with some openFrameworks examples when I got a memory access error. After a day of narrowing the problem down I have a pretty small sample of relatively pure C++ code which still causes a memory access error. I'll post the whole thing here since it's decently short.

There are three files: testApp.cpp, main.cpp, and testApp.h.

testApp.h:

#include <cstdlib>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class X {
public:

  X();
  virtual ~X();

private:

  vector<string> vertices;
  vector<string> colors;
  vector<string> normals;
  vector<string> texCoords;
  vector<string> indices;
  bool bVertsChanged, bColorsChanged, bNormalsChanged, bTexCoordsChanged, bIndicesChanged;
  int mode;
  string name;

  bool useColors;
  bool useTextures;
  bool useNormals;
};

class testApp{

public:
  void setup();

  X x1;
  X x2;
  vector<string> stroke;
};

testApp.cpp:

#include "testApp.h"

X::X() {}
X::~X() {}

void testApp::setup(){
  std::cout << stroke.size() << std::endl;


}

main.cpp:

#define _GLIBCXX_DEBUG
#include "testApp.h"

int main( ){

    testApp* o = new testApp();
    o->setup();
    std::cout << o->stroke.size() << std::endl;

}

To compile, I typed: g++ -o testApp testApp.cpp main.cpp. (I'm using Ubuntu 12.04 with the stock g++ compiler version 4.6.3, x86_64 architecture). When I run it, I get this output:

18446744073709025734
0

The first number comes from calling testApp::setup, which prints out stroke.size() (which is obviously incorrect). The second number comes from printing stroke.size() directly. It seems like there's some sort of memory issue, but I don't know where to begin, or where to file a bug.

This seems to happen only when the testApp class is specified exactly like it was. If you comment out a single vector (or even a bool) the problem goes away. The problem also goes away if you comment out _GLIBCXX_DEBUG, but that flag is supposed to be benign AFAIK. Any advice? Where should I file a bug? Or is there something obvious I've overlooked?

Also, would anyone mind trying this on their own computer/compiler to see if they get the same problem?

noisecapella
  • 814
  • 7
  • 17

1 Answers1

5

_GLIBCXX_DEBUG likely changes the definitions of the Standard Library containers, so your program violates the One Definition Rule (ODR). The definition of X is different in the main.cpp translation unit and in the testApp.cpp translation unit, yielding undefined behavior.

Community
  • 1
  • 1
James McNellis
  • 348,265
  • 75
  • 913
  • 977
  • Thanks for your answer! So you mean that X is different because it contains fields using standard libraries, which would have subtle changes due to `_GLIBCXX_DEBUG`? – noisecapella Aug 08 '12 at 19:25
  • That is my guess. If so, you'll want to use `_GLIBCXX_DEBUG` consistently across all of your translation units (likely by defining it on the command line or in a header file that everything includes). This is just a guess based on experience, though: I'm not that familiar with gcc or glibc, and I can't find any documentation for this macro. – James McNellis Aug 08 '12 at 19:26
  • I found `_GLIBCXX_DEBUG` when I was trying to flush out out-of-bounds errors with vectors. Defining that causes an exception to be thrown in that case, when using the index operator. Found about it here: http://stackoverflow.com/questions/1290396/how-to-make-stdvectors-operator-compile-doing-bounds-checking-in-debug-but – noisecapella Aug 08 '12 at 19:34
  • I see. Well then, from [the documentation](http://gcc.gnu.org/onlinedocs/libstdc++/manual/bk01pt03ch17s03.html#debug_mode.using.mode) linked by that answer, "this flag changes the sizes and behavior of standard class templates such as `std::vector`, and therefore you can only link code compiled with debug mode and code compiled without debug mode if no instantiation of a container is passed between the two translation units." – James McNellis Aug 08 '12 at 19:40