Run-Time Check Failure #3 - The variable 'GsiReturnObj' is being used without being initialized.

Write your question here.
Cant figure this one out. What am I missing?
Run-Time Check Failure #3 - The variable 'GsiReturnObj' is being used without being initialized.
(check comments on line 3 and 20)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 Gsi* Gsi::gsiBridge(const char* components[], double* dataArray, int dataArraySize)
	{
		Gsi* GsiReturnObj; //initialized here!!
		//convert array to vector
		std::vector<double> dataVector(dataArray, dataArray + dataArraySize);

		CalculateGlassModel::GlassMassMinimizationOutput glassMassMinimizationOutput;//constructor 	
		glassMassMinimizationOutput = CalculateGlassModel::Calculations::MinimizeWasteMassHLW2016(dataVector);

		if (glassMassMinimizationOutput.ErrorMessages.size() != 0)
		{
			cout << "Error while running HLW 2016" << endl << endl;

			//output error messages
			//outputTextLines(glassMassMinimizationOutput.ErrorMessages);
			GsiReturnObj->succsess = 1;
		}
		else//fill arrays to return to gsi
		{
			transferValues(GsiReturnObj, glassMassMinimizationOutput);//this is where the exception is thrown
			GsiReturnObj->succsess = 0;
		}
		return GsiReturnObj;
	}
Last edited on
You say "initialized here", but it's not being initialized there. It's a pointer to a Gsi, but the pointer "points" to an arbitrary location. Try
 
Gsi* GsiReturnObj = new Gsi;

And remember to delete it at some point.
Last edited on
Thanks tpb, the problem with that solution is that as soon as I delete the GsiReturnObj, I loose my char** values that I transferred from GsiReturnObj to glassMassMinimizationOutput (that's what the transferValues function does on line 20).

transferValues(GsiReturnObj, glassMassMinimizationOutput);
Is there a way around this?
Last edited on
Is there a way around this?

There's always some way to do it.
What does transferValues look like?
And what does a GsiReturnObj look like?
What do you mean by " I loose my char** values"? Do you mean that the pointers in your glassMassMinimizationOutput object end up pointing to invalid memory, after you delete GsiReturnObj?

If so, my guess would be that you're not properly doing a deep copy of the data - you're just copying pointer values around. Obviously, if those pointers are pointing to dynamically allocated memory, they'll be invalid once that memory has been freed.

(It's just a guess, because you've decided not to show us the code.)
Last edited on
Sorry, there is a lot of code so i'm trying to keep it simple. This is not exactly the same, but I think if I can figure out how to make this work it will solve my problem.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
char* doThis(char* str2)
{
	char str1[] = "I'm hungry";	
	strcpy(str2, str1);	
	cout << str2;
	return str2;
}

int main()
{
	char str2[] = "";
	char* test = doThis(str2);
	cout << test;
}

This code throws this exception :Run-Time Check Failure #2 - Stack around the variable 'str2' was corrupted.
str1 needs to stay in the doThis function and str2 needs to stay in main.
At line 11, you initialise str2 to be an empty string, i.e. an array with 0 length. I'm not sure that's even legal (it's been a long time since I've had to work with C-style strings).

Then, at line 4, you're trying to copy 10 characters, to an address pointing to memory that hasn't been assigned to store that many characters. You're writing past the end of the array pointed to by str2, hence corrupting the stack.

You need to make sure that when you copy data to an array - or to memory anywhere - that you've assigned enough memory to store that data.

One approach is to assign a chunk of memory when you create the array on the stack:

1
2
3
4
5
const site_t MAX_LEN = 256;  // A size you think will be enough for whatever you want to do with it

// ...

char str2[MAX_LEN];


and check you're not exceeding that memory whenever you write to it.

A better approach is to dynamically allocate the right amount of memory at the point where you need it, i.e. in your doThis() function.

However, the best approach is to save yourself the trouble, and reduce the risk of introducing errors, by just using the std::string class that's supplied by the standard library. Since this is, y'know, a C++ forum.
Last edited on
As MikeyBoy said previously, it's probably a shallow-copy vs deep-copy problem.
Here's an example of the difference.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <iostream>
#include <cstring>
using namespace std;

struct Gsi {
    size_t size;
    char **p;

    ~Gsi() {
        for (size_t i = 0; i < size; i++)
            delete [] p[i];
        delete p;
    }
};

struct Other {
    size_t size;
    char **p;

    ~Other() {
        for (size_t i = 0; i < size; i++)
            delete [] p[i];
        delete p;
    }
};

// A shallow copy just copies the pointer
void shallow_copy(const Gsi *g, Other *o) {
    o->p = g->p;
    o->size = g->size;
}

// A deep copy makes it's own copy of the underlying data
void deep_copy(const Gsi *g, Other *o) {
    o->size = g->size;
    o->p = new char*[o->size];
    for (size_t i = 0; i < o->size; i++) {
        o->p[i] = new char[strlen(g->p[i]) + 1];
        strcpy(o->p[i], g->p[i]);
    }
}

int main() {
    Gsi *g = new Gsi;

    g->size = 3;
    g->p = new char*[g->size];
    for (size_t i = 0; i < g->size; i++)
        g->p[i] = new char[10];

    strcpy(g->p[0], "hello");
    strcpy(g->p[1], "world");
    strcpy(g->p[2], "yo");

    Other *o = new Other;

    shallow_copy(g, o);
    // Only the pointer has been copied.
    // The underlying data is shared.
    // If the g's destructor deletes the underlying data
    // then it is no longer valid for o to access it anymore.

    deep_copy(g, o);
    // Now o has it's own copy of the underlying data
    // so it doesn't matter that g deletes it's data.

    delete g;

    // o's data is still okay to access
    for (size_t i = 0; i < o->size; i++)
        cout << o->p[i] << '\n';

    delete o;
}

Thanks tpb, that is very helpful!
Topic archived. No new replies allowed.