What could be causing this c++ bus error?

A friend of mine is working on a c++ program. He came to me a few days ago for help with a strange bus error.

By simply declaring an additional ostream pointer as a member of any of his classes, a bus error is given at runtime.

It doesn’t matter which of the ~5 classes it is declared in, just the act of declaring one as as a member of a class, without any initialization or usage, causes a bus error to occur.

I’m having him track down the exact line at which the bus error occurs. The last he told me, it happens while he is reading in characters from a file (of a completely different ostream). Without the additional ostream pointer declared, the program works exactly as it should.

Any ideas on what could be causing this?

Let me see if I understand you. He has a class A, something like this:


class A {
private:
    int x;
    float y;
public:
//whatever
};

When he changes it to:


class A {
private:
    int x;
    float y;
    std::istream * in;
public:
//whatever
};

then compiles and runs his program, he gets a bus error.

Do I have that right? If so, the problem is with his Makefile. It doesn’t have the header dependencies in it. So basically, when he compiles, not everything that uses class A gets recompiled, so somewhere something is using an A * using the old definition without the istream *. Probably what happens is that a virtual method gets called and jumps to a totally bogus address.

To check if I’m right, have him do a make clean and then a make. That should get rid of the problem temporarily. If he changes his class definitions later, though, he’ll likely hit the same issue. The permanent solution is to fix the Makefile.

If I had to take a guess, I’d say that his program probably already has a bug relating in some way to improper memory use, and it’s just not made manifest until another pointer is declared. Does he have any way to check the output and other indications of the program’s health, without that extra pointer?

It’s a runtime error, not a compile error, I’m certain. The general idea of the code you posted is correct though.

It appears this may be on the right track. He just gave me a call, and informed that the line of code where the bus error occurs is a delete. The program has to repeatedely allocate and delete memory assigned to a class pointer. That is, somewhere he has classA *ptr declared. Every time just before executing a ptr = new classA() he has if(ptr != NULL) delete ptr; If he takes the one instance of the if(ptr…) out there is no longer a bus error. The ptr varaible is the only one that uses dynamic allocation.

I just read online that checking for NULL before deleting is unecessary in c++, but it shouldn’t harm things.

I’ll have him investigate other memory management issues.

Thanks.

Edit: Ah, the problem might have just occured to me. Deleting doesn’t set the ptr to zero, it just deletes the allocated memory, right? So he may be deleteing the same ptr twice. If he puts ptr = 0 after every delete, this should fix things, yes?

I responded improperly to Rysto, and it’s too late to edit.

He does a make clean before every compile anyway, so that wouldn’t be the problem.

I’m not sure how you’d get a bus error from deleting memory twice, but yes, setting a pointer to 0 after you’ve deleted it certainly can’t hurt anything. Of course, if you have a second pointer to the same memory location, that setting the first pointer to 0 won’t help you. For example:


int * p = new int;
int * p2 = p;

delete p;
p = 0;

delete p2;

is erroneous.

It appears avoiding the double deleting did in fact remedy the bus error. Whether it actually addressed what was wrong, or just hid it away again, is another question.

In most cases when you declare an object of a certain class, the compiler will generate code to run the constructors for any static members that class has. This code gets run before your main() is called and the specifics of this are compiler dependent. iostream definitely has some static members (locale IDs and such).

I’ve had something very similar happen once when I was using a custom linker script – apparently the GNU linker really did not like me reordering some sections and generated improper relocation data for the .ctors section causing constructor offsets to be computed incorrectly. This resulted in the program jumping into the middle of a destructor for the same object instead and caused a nasty crash. I am not saying this is what’s going on (most likely it’s not) but if the bus error occurs before any main() code is run, the likely culprit is the STL headers – if they are horribly mismatched to the STL binary the program might still compile and link but really bad things will happen.