Sign in to follow this  
assainator

custom CBL question

Recommended Posts

heey all, i'm reading a book about scripting languages (game scripting mastery(good book by the way)) and on the hand of the first chapter about command based languages, i've written my own script loader. It runs fine, but when it is "done" (it's done with all i want it to do (print "ScriptSystem: >>Loaded script")) i get a error:
Quote:
Debug Assertation Failed! Program: C\CommandScriptLanguage\Debug\CommandScriptLanguage.exe file: f:\dd\vctools\crt_bld\self_x86\crt\src\dbgheap.c line 1317 Expression _CrtIsValidHeapPointer(pUserData) For information on how you program can cause assertion failure, see the Visual C++ documentation on asserts
i'm on windows Vista with Visual C++ Express By the way: i don't even have a "f" drive...... the code
#include <stdio.h>
#include <stdlib.h>

class ScriptSystem
{
	public:
		ScriptSystem();
		~ScriptSystem();
		void LoadScript(char *scriptFile, bool provide = false, int lines = 0);
		int iCountLines(char * scriptFile);

	private:
		char** Script;

};

ScriptSystem::ScriptSystem()
{
	Script = (char **) malloc(sizeof(char *));
}

ScriptSystem::~ScriptSystem()
{
	free(&Script);
}

void ScriptSystem::LoadScript(char *scriptFile, bool provide, int lines)
{
	if(!provide)
	{
		lines = iCountLines(scriptFile);
	}
	FILE* scriptStream;
	fopen_s(&scriptStream, scriptFile, "r");

	char** Script = ( char ** ) malloc ( lines * sizeof ( char * ) );
	int iCurrLine = 0;

	for(int iCurrLine = 0; iCurrLine < lines; iCurrLine++)
	{
		Script[iCurrLine] = (char *) malloc(99+1);
		fgets(Script[iCurrLine], 99, scriptStream);
	}

	printf("ScriptSystem: >>Loaded script\n");
}

int ScriptSystem::iCountLines(char * scriptFile)
{
	FILE* scriptStream;
	fopen_s(&scriptStream, scriptFile, "r");

	char line[100];
	int iCurrline = 0;

	while(fgets(line, 99, scriptStream))
	{
		iCurrline++;
	}
	return iCurrline;
	fclose(scriptStream);
}

ScriptSystem scr;
int main(int argCount, char **argValue)
{
	scr.LoadScript(argValue[1]);
	scr.~ScriptSystem();
	return 0;
}

[/code]

Thanks in advance,
    assainator

Share this post


Link to post
Share on other sites
Don't call the destructor manually. It is already called for you automatically. As a result, it now gets called twice, which is Bad(TM).

By the way, your code ignores the 'Script' member of the class and instead loads the data into memory allocated locally within LoadScript(), which is then never deallocated.

Oh, and the call to free() should pass 'Script' directly, rather than its address.

Oh, and you would need to deallocate the individual char* allocations as well as the containing char**.

Might I make a suggestion? If you want to use C++, use C++. Its standard library provides a variety of tools that make all of this much, much easier and more straightforward.

In modern C++, your program looks more like this:


#include <string>
#include <vector>
#include <iostream>
#include <fstream>

using namespace std;

class Script
{
public:
// Instead of making parameters to say whether other parameters
// are valid (which makes things quite complicated for the
// calling code), use function overloads. Also, use constructors
// to construct objects, i.e. to set their initial state.
Script(const std::string& filename);
Script(const std::string& filename, int count);
private:
std::vector<std::string> lines;
};

Script::Script(const std::string& filename)
{
ifstream stream(filename.c_str()); // voila, it's open.
string line;

while (std::getline(stream, line)) { lines.push_back(line); }
// voila, done. No memory allocation work. No length limits on
// either the file or on individual lines. No wasting the space for
// an entire buffer for a blank line.

cout << "ScriptSystem: >>Loaded script\n";
}

// There are ways to make the two constructors reuse a common body and avoid
// redundancy, but I'm trying to keep this example as easy to understand as
// possible.
Script::Script(const std::string& filename, int count)
{
ifstream stream(filename.c_str());
string line;

for (int i = 0; i < count; ++i) {
if (std::getline(stream, line)) { lines.push_back(line); }
else { break; } // the file ran out of lines earlier than expected.
}

cout << "ScriptSystem: >>Loaded script\n";
}

int main(int argCount, char** argValue) {
// Don't make things global when you don't have to.
Script s(argValue[1]); // yes, it will get converted to std::string automatically.
// Boom, we're done.
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this