Linked List causing Crash on Start
by Robert Fritzen · in Technical Issues · 07/17/2011 (11:30 am) · 3 replies
Hello, I'm having a problem with a linked list definition.
It's crashing as soon as I try to add an item to the list.
No idea why it's crashing. This same code was working 2 days ago, and I haven't made any changes here.
I'm getting an Access Violation Reading Location crash.
It's crashing as soon as I try to add an item to the list.
class ItemDefinitions {
private:
.
.
typedef struct itemNode {
String item;
itemNode *next;
};
itemNode *head;
.
public:
.
.
};ItemDefinitions::ItemDefinitions() {
head = NULL;
declareItems();
}
void ItemDefinitions::declareItems() {
//call exec on the store
Con::evaluatef("AssignDefinitions();"); //adds the items to the list.
//validate and activate
itemList->validateItems();
itemList->activate();
}
void ItemDefinitions::addItem(const char * itemDetails) {
itemNode * newNode;
itemNode * nodePtr;
newNode = new itemNode;
newNode->item = itemDetails;
newNode->next = NULL;
if(head == NULL) {
head = newNode;
}
else {
nodePtr = head;
while(nodePtr->next != NULL) {
nodePtr = nodePtr->next;
}
nodePtr->next = newNode;
}
}No idea why it's crashing. This same code was working 2 days ago, and I haven't made any changes here.
I'm getting an Access Violation Reading Location crash.
About the author
Illinois Grad. Retired T3D Developer / Pack Dev.
#2
Output:
07/17/2011 (1:41 pm)
This still does not work (even with provided fixes). Here is the entire code, since it seems that it could potentially be linked to some other issue?//HEADER
#ifndef _ITEMDEFS_H_
#define _ITEMDEFS_H_
#include "console/console.h"
#include "console/consoleInternal.h"
#include "platform/platform.h"
#include "console/simBase.h"
#include "console/consoleTypes.h"
#include "console/scriptObjects.h"
#include "console/simBase.h"
#include "core/strings/stringUnit.h"
#include "console/PGDCrypto/cryptoPackage.h"
#define _DEBUG 1
class ItemDefinitions {
private:
int itemCount;
bool active;
//linked list
struct itemNode {
public:
itemNode(void) : item(NULL), next(NULL) {}
~itemNode(void) { if (next != NULL) delete next; }
String item;
itemNode *next;
};
//end
itemNode *head;
InvertibleRSAFunction keys;
static const int costVar[];
public:
ItemDefinitions();
~ItemDefinitions();
static void create();
static void destroy();
void validateItems();
void activate();
void addItem(const char * itemDetails);
void declareItems();
};
extern ItemDefinitions* itemList;
#endif
//CODE
#include "console/PGDCrypto/itemStore.h"
ItemDefinitions* itemList = NULL;
const int ItemDefinitions::costVar[] = {100, 1000, 2500, 5000, 10000, 50000, 250000, 500000, 1000000};
void ItemDefinitions::create() {
if(itemList == NULL) {
itemList = new ItemDefinitions();
}
}
void ItemDefinitions::destroy() {
delete itemList;
itemList = NULL;
}
ItemDefinitions::ItemDefinitions() {
itemCount = 0;
active = false;
keys = cryptoPackage->rsaGenerate(512);
declareItems();
}
ItemDefinitions::~ItemDefinitions() {
}
void ItemDefinitions::validateItems() {
std::string sign, toSign;
//for(int i = 0; i < itemCount; i++) {
itemNode *nodePtr = head;
while(nodePtr->next) {
sign = "", toSign = "";
toSign = string(nodePtr->item.c_str());
//do signing here...
cryptoPackage->rsaSign(keys, toSign, sign);
//append it to the string
//item[i].AppendString("t");
nodePtr->item += 't';
nodePtr->item += sign.c_str();
nodePtr = nodePtr->next;
}
}
void ItemDefinitions::activate() {
active = true;
std::string test, signature;
itemNode *nodePtr = head;
while(nodePtr->next) {
//strip the fields
test = Con::getReturnBuffer( StringUnit::getUnits(nodePtr->item.c_str(), 0, 5, "tn") );
//strip the signature
signature = Con::getReturnBuffer( StringUnit::getUnit(nodePtr->item.c_str(), 6, "tn") );
//verify the signature
if(cryptoPackage->rsaVerify(keys, test, signature) == false) {
active = false;
break; //signature invalidation detected, the activation will now halt.
}
nodePtr = nodePtr->next;
}
}
void ItemDefinitions::addItem(const char * itemDetails) {
itemNode *NewNode;
NewNode = (itemNode*)malloc(sizeof(itemNode)); //allocate space for node
NewNode->item = itemDetails;
NewNode->next = head;
head = NewNode;
}
void ItemDefinitions::declareItems() {
//call exec on the store
Con::evaluatef("AssignDefinitions();");
//validate and activate
itemList->validateItems();
itemList->activate();
}
ConsoleFunction(addItem, void, 2, 2, "adds an item to the list.. not validated until ValidateItems()") {
itemList->addItem(argv[1]);
}Output:
'BattlelordAD.exe': Loaded . . . 'BattlelordAD.exe': Loaded 'C:WindowsSysWOW64msimg32.dll' 'BattlelordAD.exe': Loaded 'C:WindowsSysWOW64msvcr71.dll' 'BattlelordAD.exe': Loaded 'C:WindowsSysWOW64XAudio2_7.dll' 'BattlelordAD.exe': Loaded 'C:WindowsSysWOW64rsaenh.dll' First-chance exception at 0x0066fdef in BattlelordAD.exe: 0xC0000005: Access violation reading location 0x00000008. Unhandled exception at 0x0066fdef in BattlelordAD.exe: 0xC0000005: Access violation reading location 0x00000008.
#3
07/20/2011 (6:30 am)
After chatting with Robert MacGregor (one of my fellow dev team members), we sorted this issue out. I was incorrectly initializing my linked list (IE: trying to validate items in it before the list was even filled).
Robert MacGregor
Phantom Games Development
void ItemDefinitions::addItem(const char * itemDetails) { itemNode * newNode; itemNode * nodePtr; newNode = new itemNode; newNode->item = itemDetails; newNode->next = NULL; if(head == NULL) { head = newNode; } else { nodePtr = head; while(nodePtr->next != NULL) { nodePtr = nodePtr->next; } nodePtr->next = newNode; } }I believe your code there is causing the issue, I'm using linked lists in my own software (not related to Torque) and it's working fine. However it is using a different method of adding elements to your linked list (works under GCC, I'm not sure about MSVC):
#include <string> struct LinkedListNode { public: LinkedListNode(void) : itemData(NULL), Next(NULL) { } ~LinkedListNode(void) { if (Next != NULL) delete Next; } //! Data std::string itemData; LinkedListNode *Next; }; LinkedListNode *linkedListHead = NULL; void addElement(std::string element) { LinkedListNode *NewNode; NewNode = (LinkedListNode*)malloc(sizeof(LinkedListNode)); //allocate space for node NewNode->itemData = element; NewNode->Next = linkedListHead; linkedListHead = NewNode; }