7
votes

I am trying to define a variable from an external library in C++, Visual Studio 2010. It only works when I put it outside of the main function.

This code crashes:

#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>

int main()
{
   ogdf::Graph g;
   ogdf::randomSimpleGraph(g, 10, 20);
   return 0;
}

It gives me an unhandheld exception: Access violation. However, if it is outside main function, it works without any problem:

#include "StdAfx.h"
#include <ogdf\basic\Graph.h>
#include <ogdf\basic\graph_generators.h>

ogdf::Graph g;

int main()
{
   ogdf::randomSimpleGraph(g, 10, 20);
   return 0;
}

Do you have any how do I fix that? I assume, that it is caused by some kind of linking problem.

EDIT: It looks like the problem is not the initialization of the variable. It throws an exception, when the application exits.

int main()
{
ogdf::Graph g; // No problem
ogdf::randomSimpleGraph(g, 10, 20); // No problem
int i; // No problem
std::cin>>i; // No problem
return 0;    // Throws an exception after read i;

}

Call stack: Call STack

The output is: First-chance exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.

Unhandled exception at 0x0126788f in graphs.exe: 0xC0000005: Access violation writing location 0x00000000.

1
It probably have something to do with that global variables are zero-initialized, while local variables have indeterminate values. What if you explicitly zero-initialize g when declared locally?Some programmer dude
@JoachimPileborg: but ogdf::Graph is a class and the constructor hopefully does the initialisation stuff. Documentation is hereJabberwocky
Can you also post the stack dump. It would be interesting where the exception is raised, and because of which address.Flovdis
Problems in the destructor?Some programmer dude
You could try with new/delete and verify if the destructor of g throws, or if its some global object in the linked library that throws on program exit. Could be a bug in the library where a pointer to g is kept somewhere in a global var that will access it in the destructor.Bgie

1 Answers

5
votes

Works on my machine™.

Esoteric errors like that are often a result of binary incompability. Basically, because of different compiler/preprocessor options, effective headers that your code and the library "see" are different.

For instance, if you have a library with following header code:

class Foo
{
#ifdef FOO_DEBUG
    int debug_variable;
#endif
    int variable;
};

Library function:

void bar(Foo& foo)
{
    std::cout << foo.variable;
}

And client code:

Foo foo;
foo.variable = 666;
bar(foo);

If FOO_DEBUG is not in sync amongst client and the library, this will possibly crash and burn -- variable will have different expected offset.

In your case, I suspect one of the following may be true:

  • You have built the ogdf with different compiler than your code
  • If not, you ogdf and your code have different build configurations (Release vs Debug)
  • Both are debug, but you have defined OGDF_DEBUG (as recommended here)
  • You have different "Struct Member Alignment" setting