This might be very specific. So I don't really "expect" some direct answers here, but any help (as long as it's correct) is helpful..
I used to program in GameMaker, and I like it still, now a new library is made to incorporate gamemaker functions inside a C++ program: very usefull for direct communication!
[url=
http://gmc.yoyogames.com/index.php?showtopic=420970]here is the topic about it[/url]
Now the first code allocates memory for the "string-part" of a variable by calling 'malloc'. So I had to do a small rewrite of the GMVariable class which now looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
class GMVariable
{
private:
int type;
double real;
char* string;
int padding;
public:
GMVariable();
GMVariable(double a);
GMVariable(int a);
GMVariable(char* a);
GMVariable(std::string a);
GMVariable(const GMVariable& v);
~GMVariable();
operator double();
operator char*();
GMVariable const operator-(const GMVariable& v );
GMVariable const operator+(const GMVariable& v );
GMVariable const operator*(const GMVariable& v );
GMVariable& operator=(const GMVariable& v);
bool isReal();
bool isString();
};
|
The default constructor:
1 2 3 4 5 6 7
|
GMVariable::GMVariable()
{
type = 0;
real = 0;
string = 0;
padding = 0;
}
|
One of the other constructors now works like this:
1 2 3 4 5 6 7 8 9 10
|
GMVariable::GMVariable(std::string a) {
char* n;
n = (char*) malloc(a.length() + 5);
*((unsigned int*)n) = a.length();
strcpy(n + 4, a.c_str());
type = 1; //type (0,1) means whether it's a real(0) or string(1)
real = 0; //real part
string = n + 4; //string part (length followed by a c-style-string)
padding = 0;
}
|
And the destructor looks like:
1 2 3 4 5
|
GMVariable::~GMVariable() {
if (this->string != NULL) {
free(string-4);
}
}
|
Copy constructors (and all other constructors) work correctly with allocating the memory which is needed etc.
The problem however is in this function:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
|
GMVariable ExternalCall(GMPROC* proc, int argsUsed, int argCount, GMVariable* args)
{
GMVariable ret;
if(argCount < 15) argsUsed = 0;
DWORD t; t = (DWORD)&ret;
__asm
{
push (args);
push (argCount);
push (t);
mov ecx, (argsUsed);
call (proc)
};
return ret;
}
|
Above function is called when you try to execute a "gamemaker-native-function".
GMPROC* proc = a pointer to a procedure of a gamemaker function.
int argsUsed, int argCount = Number of arguments the gamemaker function takes
GMVariable* args = an array filled with "GMVariable" objects..
Firstly it constructs GM-Variable with the default constructor.. But afterwards the object is filled by the ASM (especiall the "call (proc)", which executes the GameMaker function).
And the variables are (for example:)
type = 0;
real = 0;
string = "5";
padding = 0;
Also the memory (4 positions) before the "string" are set correctly:
int i = *(string-4); sets "i" to the length of the string (1 in above example)..
However when it's going out of above function: and thus destroying "ret", it crashes complaining about a corruption of the heap! - This happens exactly at the "free()" command of the destructor.
So my question is:
How to "free" the memory allocated by the assembly? - Or is it freed automatically?