bad_alloc too soon

I have written a program that has to deal with a few thousand elements (mostly unsigned int, but new[] keeps throwing a bad_alloc exception.

The code for the problematic function is here, but is fine as far as I can see.
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
elements sort_elements(char DAT)
{
	int i,j;
	elements elems;
	int a=find_prop();
	unsigned int* m = new unsigned int[IupGetInt(num_faults,"VALUE")];
	unsigned int** ints;
	if(a)
	{
		elems.start(a);
		ints = new unsigned int*[IupGetInt(num_faults,"VALUE")];
		for(i=0;i<IupGetInt(num_faults,"VALUE");i++)
		{
			m[i]=find_prop(IupGetAttribute(dat_list->faults[i].txt,"VALUE"));
			ints[i]=new unsigned int[m[i]]; //THIS IS WHERE THE bad_alloc IS THROWN
			for(j=0;j<a;j++)
			{
				fscanf_s(txt," %d",&ints[i][j]);
				fseek(txt,64,SEEK_CUR);
			}
			rewind(txt);
		}
		elems.join(ints,m);
		for(j=0;j<IupGetInt(num_faults,"VALUE");j++)
			delete[] ints[j];
		delete[] ints;
	}
	else
		IupMessage("Erro","Uma propriedade nao foi achada no DAT");
	delete[] m;
	return elems;
}

The for-loop runs once, allocating 300+ with no problems, and then throws a bad_alloc the second time around at 200+.

Admittedly, I have allocated memory left and right outside of this function, but I doubt that's the problem. I ran it with Windows Task Manager on and it dies at a mere 10,152K, while Firefox is taking up 244,568K.

I guess I should put a question here, so...

Help?

EDIT:: And, evidently, I forgot to say I'm on VC++ 2008 Express
Last edited on
What value is IupGetInt(num_faults,"VALUE") returning?
What value is find_prop(IupGetAttribute(dat_list->faults[i].txt,"VALUE")) returning?
IupGetInt() returns 2, while find_prop() returns 210 and then 318 or visa-versa. It depends on the order of some initial input on my part. As I said, it allocates the first time and then stumbles on the second, regardless of order.

EDIT: I can also change my initial input so that it IupGetInt returns only 1 and then choose which list I want to compile (210 and 318 are the number of elements in each list in a .txt file, while IupGetInt() effectively returns the number of lists I want to compile). The program has no problems doing either list. Just not both together.

I also have another .txt file with smaller lists (60,30,20 elements each) and the program has no problem compiling all of them at once. It really just seems to be a size issue.
Last edited on
I don't really understand a lot of this. For example, why is
for(j=0;j<a;j++)
not
for(int j = 0; j < m[i]; ++j)

And why are you deleting like this?
1
2
for(j=0;j<IupGetInt(num_faults,"VALUE");j++)
    delete[] ints[j];

and not this?
1
2
for(int j = 0; j < m[i]; ++j)
    delete[] ints[j];


I suggest you sort out your indexes before pointing your finger at the heap.
kbw wrote:
And why are you deleting like this?
Because i has no meaning at that scope, and m[i] is the individual size of each array in the array of pointers, not the size of the array of pointers itself.

I agree about the a vs. m[i] part, though. You should at least verify that a<=m[i].
Last edited on
There are, of course, lots of other functions hidden from your view. I think it best to give some background.

This program opens a .txt file containing an X number of lists, each of which is defined by a property name.

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
elements sort_elements(char DAT)
{
	int i,j;
	elements elems;
	int a=find_prop(); /*find_prop(void) checks that all declared properties
			(contained in a global string variable and therefore
			available to all functions) exists and returns the total
			number of elements desired*/
	unsigned int* m = new unsigned int[IupGetInt(num_faults,"VALUE")];
	/*IupGetInt returns the number of faults (lists) desired.*/
	unsigned int** ints;
	if(a)
	{
		elems.start(a); /*elems is basically a class containing two arrays
				of ints, one with the elements desired and one with the
				fault each element is contained in. This allows all elements
				to be dealt with later on in the program. elems.start(a)
				simply initializes each of these arrays with /a/ elements*/
		ints = new unsigned int*[IupGetInt(num_faults,"VALUE")]; /*ints
		is a pointer-array where each pointer points to an array containing
		all the elements of each fault*/
		for(i=0;i<IupGetInt(num_faults,"VALUE");i++)
		{
			m[i]=find_prop(IupGetAttribute(dat_list->faults[i].txt,"VALUE"));
			/*find_prop(char* prop) finds a specific property (defined in
			dat_list->fault[i].txt) and returns the number of elements of
			this property. m[i] is therefore the number of elements in fault i*/
			ints[i]=new unsigned int[m[i]]; /*ints[i] is therefore the list of
			elements in each fault and therefore must be declared in terms
			of m[i] which is the number of elements in each fault*/
			for(j=0;j<a;j++)
			{
				fscanf_s(txt," %d",&ints[i][j]);
				fseek(txt,64,SEEK_CUR);
			}
			rewind(txt);
		}
		elems.join(ints,m); /*elems.join receives ints and m and joins all the
				separate faults in two separate arrays, one containing all
				the elements in ascending order and the other containing
				the fault which each of those elements is contained
				(elems.element[i] is found in fault elems.fault[i]*/
		for(j=0;j<IupGetInt(num_faults,"VALUE");j++)
			delete[] ints[j]; /*must delete each sub-array of ints before
					deleting ints itself*/
		delete[] ints;
	}
	else
		IupMessage("Erro","Uma propriedade nao foi achada no DAT");
	delete[] m;
	return elems;
}


I hope this has cleared things up a bit. I simply can't copy the entire program since it's around 1700 lines long.
Last edited on
I realise it's a bit frustrating when things don't appear work as they should for no apparent reason. But the fact is, if you can't reproduce it in a minimal program, the problem probably doesn't exist.

I'm not convinced that you've verified the correctness of your program and from what I've seen, there's scope for error.

You should appreciate that it's frustrating for us to spend time on problems that don't really exist. I say you should either reproduce the problem in a very small app or remove the complexity from your code as a rule.
That's not true. A very small mistake in a large program can produce a deterministic error elsewhere, and there's no way you're going to reproduce it by writing a different program.
Also, it's worth mentioning the program does quite a bit more than simply make an array of elements. I work in a geotechnics lab and my program is gets results from our finite-element analysis.

All that said, I actually agree with you guys. What the hell is that a doing in that for? If the problem is really just that, I'm going to go on a killing spree.

Hoping you guys would show me this sort of thing, I brought back all the resource files (700MB each) home from work so that I could work on it during the weekend. Obviously, in all my wisdom, I forgot the actual program code... But we'll see on Monday.
Topic archived. No new replies allowed.