Linker causing seemingly random crashes? - c++

EDIT: After some more trying and testing, it seems to set down to changing stack size everytime I change code and I want the program to run. If I don't change the stack size, the program seems to crash everytime after code change.
EDIT 2: Same seems to apply to both /HEAP and /STACK
A bit of and odd question, but as far as I can tell, based on some checking and testing.
On multiple projects (at some point) I've come across this same problem:
I change a bit of code, the program crashes.
I change stack size, the program doesn't crash(with the changed code), doesn't seem to matter if incrementing or decrementing stack size.
Seemingly as if there's a hidden randomized stack which, if below a certain value causing the program to crash (no error). I can cause the crash by testing different stack sizes.
On a recent project, the crash seems to "pinpoint" to the bit of code:
typedef unsigned int DINT;
template <typename LIST_ITEM>
struct LIST {
LIST() {
this->length = 0;
this->total = 0;
for (DINT i = 0; i < ENGINE_DATABASE_LIST_LENGTH_MAX; i++) {
//this->item[i] = { 0 };
this->existance[i] = 0;
}
};
~LIST() {
for (DINT i = 0; i < ENGINE_DATABASE_LIST_LENGTH_MAX; i++) {
//this->item[i] = { 0 };
this->existance[i] = 0;
}
this->length = 0;
this->total = 0;
};
DINT length, total;
LIST_ITEM item[ENGINE_DATABASE_LIST_LENGTH_MAX];
DINT existance[ENGINE_DATABASE_LIST_LENGTH_MAX];
DINT _set(LIST_ITEM item) {
for (DINT d = 0; d < ENGINE_DATABASE_LIST_LENGTH_MAX; d++) {
if (this->existance[d] == 0) {
this->item[d] = item;
this->existance[d] = 1;
this->length++;
this->total++;
return d;
}
}
return 0;
}
void _remove(DINT position = 0) {
this->item[position] = {};
this->existance[position] = 0;
LIST <LIST_ITEM> list = {};
DINT length = 0;
do {
if (this->existance[length] == 1) {
list._set(this->_get(length));
this->existance[length] = 0;
//this->item[l] = {};
}
length++;
} while (length < ENGINE_DATABASE_LIST_LENGTH_MAX);
this->_carry(list);
}
LIST_ITEM _get(DINT position = 0) {
return this->item[position];
}
void _carry(LIST <LIST_ITEM> list = {}) {
for (DINT d = 0; d < list.length; d++) {
if (list.existance[d] == 1) this->_set(list.item[d]);
}
}
void _deconstruct() {
/*
for (DINT i = 0; i < ENGINE_DATABASE_LIST_LENGTH_MAX; i++) {
if (this->existance[i] == 1) {
this->existance[i] = 0;
this->item[i] = { };
}
}
this->length = 0;
this->total = 0;
*/
this->~LIST();
}
};
Possible solution/fix:
void _remove(DINT position = 0) {
this->existance[position] = 0;
this->length--;
LIST <LIST_ITEM> *list = new LIST;
for (DINT a = 0; a < ENGINE_DATABASE_LIST_LENGTH_MAX; a++) {
if (this->existance[a] == 1) {
list->_set(this->item[a]);
if (list->length == this->length) break;
}
}
list->total = this->total;
*this = *list;
delete list;
}
If the max list length is set to 64, the program seems to run fine, no matter of stack, but at 128 the crashes start to happen, and if I do the above (change stack size by even just 1, the program runs fine again, until next change of code, then I change stack by 1 again and the program runs fine again).
There might be a "< 0" somewhere (which could also cause crashing), which I just can't seem to spot.
Please do point out.
Seem confusing? Please ask.

Related

C++ Calculating Shortest Path in a Directed Graph

I am tasked with writing a program to maintain the representation of a simple network(weighted directed graph) and compute the best path between two given nodes upon request.
Currently, I am attempting to write a function to compute the simplest between two nodes, however, when attempting to run my program, I get two specific error
Severity Code Description Project File Line Suppression State
Error C3863 array type 'bool [openNode]' is not assignable P 127
and
Severity Code Description Project File Line Suppression State
Error C3863 array type 'int [openNode]' is not assignable
I am unable to debug since these two primary errors are not allowing my program to run. Is there any particular reason for these errors?
Thanks in advance!
This is the node structure defined in Graph.h
struct GraphNode
{
char ID;
std::string name;
int inNodes = 0;
int outNodes = 0;
std::vector<std::pair<GraphNode*, int>> connection;
int connections = 0;
};
And here is the particular code that causes the errors.
#include "Graph.h"
std::vector<GraphNode*> _graph;
int openNode = 0;
//Obligatory constructor
void Graph()
{
}
void shortestPath(char fromNode, char toNode)
{
bool known[openNode];
int distance[openNode];
GraphNode* previous[openNode];
int numbChecked = 0;
for (int i = 0; i < openNode; i++)
{
known[i] = false;
distance[i] = 999999;
previous[i] = nullptr;
}
distance[findNode(fromNode)] = 0;
while (numbChecked < openNode)
{
int smallestUnknown = 9999999;
int locationOfSmall = 0;
for (int i = 0; i < openNode; i++)
{
if (known[i] == false && distance[i] < smallestUnknown)
{
smallestUnknown = distance[i];
locationOfSmall = i;
}
}
if (distance[locationOfSmall] == 0)
{
previous[locationOfSmall] = nullptr;
}
known[locationOfSmall] = true;
numbChecked++;
if (_graph[locationOfSmall]->outNodes > 0)
{
for (int i = 0; i < _graph[locationOfSmall]->outNodes; i++)
{
int newDistanceLocation = findNode(_graph[locationOfSmall]->connection[i].first->ID);
if (known[newDistanceLocation] == false && (distance[locationOfSmall] + _graph[locationOfSmall]->connection[i].second) < distance[newDistanceLocation])
{
distance[newDistanceLocation] = distance[locationOfSmall] + _graph[locationOfSmall]->connection[i].second;
previous[newDistanceLocation] = _graph[locationOfSmall];
}
}
}
}
int destination = findNode(toNode);
std::string output;
std::string charTransfer;
charTransfer = toNode;
output = charTransfer;
while (previous[destination] != nullptr)
{
destination = findNode(previous[destination]->ID);
charTransfer = _graph[destination]->ID;
output = charTransfer + "->" + output;
}
if (_graph[destination]->ID != fromNode)
{
std::cout << "The nodes are not connected." << std::endl;
}
else
{
std::cout << "The path is: " << output << std::endl;
std::cout << "The distance is: " << distance[findNode(toNode)] << std::endl;
}
}
Any change suggestions would be much appreciated!
You have invalid code at the beginning of your shortestPath function:
bool known[openNode];
int distance[openNode];
GraphNode* previous[openNode];
You cannot use variables to create arrays on the stack (which is what you are trying to do there), because the compiler doesn't know the value of openNode at compile time (which is needed to determine the stack size).
Why don't you use a vector, like:
std::vector<bool> known(openNode, false);
std::vector<int> distance(openNode, 999999);
std::vector<GraphNode*> previous(openNode, nullptr);
Using this method makes the for loop below obsolete aswell.

Why does random extra code improve performance?

Struct Node {
Node *N[SIZE];
int value;
};
struct Trie {
Node *root;
Node* findNode(Key *key) {
Node *C = &root;
char u;
while (1) {
u = key->next();
if (u < 0) return C;
// if (C->N[0] == C->N[0]); // this line will speed up execution significantly
C = C->N[u];
if (C == 0) return 0;
}
}
void addNode(Key *key, int value){...};
};
In this implementation of Prefix Tree (aka Trie) I found out that 90% of findNode() execution time is taken by a single operation C=C->N[u];
In my attempt to speed up this code, I randomly added the line that is commented in the snipped above, and code became 30% faster! Why is that?
UPDATE
Here is complete program.
#include "stdio.h"
#include "sys/time.h"
long time1000() {
timeval val;
gettimeofday(&val, 0);
val.tv_sec &= 0xffff;
return val.tv_sec * 1000 + val.tv_usec / 1000;
}
struct BitScanner {
void *p;
int count, pos;
BitScanner (void *p, int count) {
this->p = p;
this->count = count;
pos = 0;
}
int next() {
int bpos = pos >> 1;
if (bpos >= count) return -1;
unsigned char b = ((unsigned char*)p)[bpos];
if (pos++ & 1) return (b >>= 4);
return b & 0xf;
}
};
struct Node {
Node *N[16];
__int64_t value;
Node() : N(), value(-1) { }
};
struct Trie16 {
Node root;
bool add(void *key, int count, __int64_t value) {
Node *C = &root;
BitScanner B(key, count);
while (true) {
int u = B.next();
if (u < 0) {
if (C->value == -1) {
C->value = value;
return true; // value added
}
C->value = value;
return false; // value replaced
}
Node *Q = C->N[u];
if (Q) {
C = Q;
} else {
C = C->N[u] = new Node;
}
}
}
Node* findNode(void *key, int count) {
Node *C = &root;
BitScanner B(key, count);
while (true) {
char u = B.next();
if (u < 0) return C;
// if (C->N[0] == C->N[1]);
C = C->N[0+u];
if (C == 0) return 0;
}
}
};
int main() {
int T = time1000();
Trie16 trie;
__int64_t STEPS = 100000, STEP = 500000000, key;
key = 0;
for (int i = 0; i < STEPS; i++) {
key += STEP;
bool ok = trie.add(&key, 8, key+222);
}
printf("insert time:%i\n",time1000() - T); T = time1000();
int err = 0;
key = 0;
for (int i = 0; i < STEPS; i++) {
key += STEP;
Node *N = trie.findNode(&key, 8);
if (N==0 || N->value != key+222) err++;
}
printf("find time:%i\n",time1000() - T); T = time1000();
printf("errors:%i\n", err);
}
This is largely a guess but from what I read about CPU data prefetcher it would only prefetch if it sees multiple access to the same memory location and that access matches prefetch triggers, for example looks like scanning. In your case if there is only single access to C->N the prefetcher would not be interested, however if there are multiple and it can predict that the later access is further into the same bit of memory that can make it to prefetch more than one cache line.
If the above was happening then C->N[u] would not have to wait for memory to arrive from RAM therefore would be faster.
It looks like what you are doing is preventing processor stalls by delaying the execution of code until the data is available locally.
Doing it this way is very error prone unlikely to continue working consistently. The better way is to get the compiler to do this. By default most compilers generate code for a generic processor family. BUT if you look at the available flags you can usually find flags for specifying your specific processor so it can generate more specific code (like pre-fetches and stall code).
See: GCC: how is march different from mtune? the second answer goes into some detail: https://stackoverflow.com/a/23267520/14065
Since each write operation is costly than the read.
Here If you see that,
C = C->N[u]; it means CPU is executing write in each iteration for the variable C.
But when you perform if (C->N[0] == C->N[1]) dummy++; write on dummy is executed only if C->N[0] == C->N[1]. So you have save many write instructions of CPU by using if condition.

Why does my c++ code run fine on Windows 7 but crashes on Windows 8?

Ok, I added the following code to a mod menu for a game and everything works fine for me in Windows 7. But when I send it to my friend on Windows 8, he tries to select a button (which calls the GetClients() function) and the game just crashes. Any idea why?
char* playerNames[31] = {};
int getUID(char* pName)
{
int i = 0;
while (i < 31) {
char* pNamesec = (char*)PLAYER::GET_PLAYER_NAME((Player)(i));
if (pNamesec == pName) {
return i;
}
//else { break; }
i++;
}
}
char* getPnameAt(int id) {
for (int i = 0; i < 30; i++) {
if (i == id) {
return (char*)PLAYER::GET_PLAYER_NAME((Player)(i));
}
}
}
void GetClients()
{
playerNames[31] = {};
int i = 0;
while (i < 100) {
char* pName = (char*)PLAYER::GET_PLAYER_NAME((Player)(i));
if (wcslen((WCHAR*)pName) > 3) {
if (getUID(pName) == i) {
playerNames[i] = pName;
} else {
getPnameAt(i);
}
}
i++;
}
i = 0;
}
Error message that pops up says:
CORE: An exception occurred while executing modmenu.asi, press ok to continue
You have created an array of length 31. So you can access array playerName from index 0 to index 30. In GetClients()
playerNames[31] = {}; //Observe this line
while (i < 100) {
// Indexes greater than 30 are being used to access playerNames array
}
31 or beyond is not a valid index for playerNames array and you are getting undefined behavior.
So if you want to add in playerNames in runtime. Below is the small example that might help you..
int main()
{
vector<string> playerNames;
playerNames.push_back("XYZ");
playerNames.push_back("ABC");
// To access from vector
vector<string>::iterator itr = vec.begin();
for(;itr!=vec.end();itr++)
{
cout<<*itr<<endl;
}
}
Read more here

passing pointer to function and using realloc

I want to pass a pointer to a function which will call a second function that will use realloc.
The issue is that realloc is returning NULL.
I don't know if the mistake is in the numbers of * in the function call or something else.
Could you please help me ?
The code:
int main(){
// some code.
clause_t* ptr; //clause_t is a structure i declared.
//Some work including the initial allocation of ptr (which is working).
assignLonely(matSAT, ic.nbClause, ic.nbVar, ptr); //the issue is here.
//Some other work
}
void assignLonely(int** matSAT, int nbClause, int nbVar, clause_t* ptr)
{
int i = 0, j = 0;
int cpt = 0;
int indice = -1;
for (i = 0; i < nbClause ; ++i)
{
j = 0;
cpt = 0;
while((j < nbVar) && (cpt < 2))
{
if (matSAT[i][j] != 0)
{
cpt++;
}
else
{
indice = j;
}
if (cpt < 2)
{
deleteClause(indice, &ptr);
}
j++;
}
}
}
void deleteClause(int indiceClause, clause_t** ptr)
{
int i = indiceClause;
int nbElt = sizeof((*ptr))/sizeof((*ptr)[0]);
int tailleElt = sizeof((*ptr)[0]);
while(i+1 < nbElt)
{
(*ptr)[i] = (*ptr)[i+1];
i++;
}
*ptr = (clause_t*)realloc(*ptr, (nbElt-1)*tailleElt);
if (*ptr == NULL)
{
fprintf(stderr, "Erreur reallocation\n");
exit(EXIT_FAILURE);
}
}
You have to declarae function assignLonely similarly to function deleteClause like
void assignLonely(int** matSAT, int nbClause, int nbVar, clause_t** ptr);
if you want that changes of ptr in the function would be stored in the original object in main.
Also take into account that this statement
int nbElt = sizeof((*ptr))/sizeof((*ptr)[0]);
is wrong.
Expression sizeof((*ptr)) will return the size of the pointer. Pointers do not keep information about how many elements in arrays they point to.
So expression
(nbElt-1)
can be equal to zero or even be negative.

Error: not all control paths return a value

I am writing two functions in a program to check if a string has an assigned numeric code to its structure array or if the given numeric code has an assigned string in the same structure array. Basically, if I only know one of the two, I can get the other. I wrote the following:
int PrimaryIndex::check_title_pos(std::string title) {
bool findPos = true;
if (findPos) {
for (int s = 1; s <= 25; s++) {
if (my_list[s].title == title) {
return s;
}
}
} else {
return -1;
}
}
std::string PrimaryIndex::check_title_at_pos(int pos) {
bool findTitle = true;
if (findTitle) {
for (int p = 1; p <= 25; p++) {
if (my_list[p].tag == pos) {
return my_list[p].title;
}
}
} else {
return "No title retrievable from " + pos;
}
}
However, it says not all control paths have a return value. I thought the else {} statement would handle that but it's not. Likewise, I added default "return -1;" and "return "";" to the appropriate functions handling int and string, respectively. That just caused it to error out.
Any idea on how I can keep this code, as I'd like to think it works but cant test it, while giving my compiler happiness? I realize through other searches that it sees conditions that could otherwise end in no returning values but theoretically, if I am right, it should work fine. :|
Thanks
In the below snippet, if s iterates to 26 without the inner if ever evaluating to true then a return statement is never reached.
if (findPos) {
for (int s = 1; s <= 25; s++) {
if (my_list[s].title == title) {
return s;
}
}
}