DLyons
DLyons

Reputation: 186

"Random" output from a determinstic C++ program. Possible causes?

I'm using Microsoft Visual Studio Community 2015, Version 14.xxx on a 64-bit Windows PC.

The program reads a text file in which each line is a Bridge deal (four players each with 13 cards). The file is generated by a 3rd party program that is reliable but I validate each deal anyway and each input line passes the validation.

I then group "similar" deals together into classes (bins) based on variables such as number of points, suit length etc. This is standard text processing using stringstreams and a map of my Bin structure. It's totally deterministic for a given input file.

About 3/4 of the time I get the same output e.g. 23 possible bins - and the frequency of deals across the bins adds up to the number of input deals, as expected. But the remaining output might have anything from 6 to 50 bins (with correct frequency totals).

Where might such randomness arise? I use default initialization of all variables so, even if that were wrong, it should be consistent across program runs on a given file. For example,

std::string line;  //  Raw data on a deal.
std::vector<std::string> parsed_deal;
std::map<std::string, struct Bin> m_bin;
std::stringstream ss_bin[MAX_BINS]; 

Upvotes: 0

Views: 158

Answers (1)

Peter
Peter

Reputation: 36597

Default initialisation does not mean that all variables will be initialised in exactly the same way, every time your program is run. In particular, default initialisation means uninitialised in several circumstances. Examples include basic types (int, float, pointers, arrays of them, etc) being uninitialised (e.g. auto variables which are NOT initialised to zero), and such a member of a class type that is not actually initialised by a constructor. Accessing the value of an uninitialised variable (let alone dereferencing it if it is a pointer) gives undefined behaviour.

There are, naturally, other causes of undefined behaviour (falling off the end of an array, molesting a pointer, invoking operator delete twice on the same pointer, invoking operator delete on a pointer returned by malloc()).

If the behaviour is undefined, then "non-deterministic" behaviour is one possible outcome. For example, when a variable is defined but not initialised, its value may be based on whatever happened to be in that physical/logical memory location previously. So the result of accessing its value will depend on what other code (in your program, in your operating system, even in another process) was using that memory previously, and how/if that memory was overwritten before your program accessed it.

Upvotes: 1

Related Questions