tiny_malloc error? Urgent please !!

Pages: 1234
Can anyone help? Today I've known that I must present my work at my University next month and I blocked with this ... : (
Last edited on
Can you post your code over at pastebin or zip everything up and put it online somewhere so I can take a look at it?

I cannot promise anything, since my time is extremely limited... but it would help a lot if I could peruse the code directly.
Duoas, my code is here:

http://dl.dropbox.com/u/816233/Project.zip

I think I've got problems in Poblacion::Ruleta (seems an infite loop) and Poblacion::K_Torneo (returns the same result in the execution). I'm not sure about these problems, but the backtrace (full) of the debugger makes me think that.

Anyway......... Infinitely thanks.

Phass, I had surrendered, since I do not understand the code (and the language).

But, given the extremity of the situation I made some progress that may be useful to you. Using your backtrace to deduce the input I reproduced the behavior you describe: the program either hangs or crashes.

First, following advice regarding memory faults, I eliminated all warnings that appear with the gcc -Wall -Wextra options. Particularly, I eliminated all warnings for functions that have possible control path without return statement, because allegedly those are source of such crashes. Even if you are certain, you just can not leave functions like that. Also, I inserted casts for the result of all size() functions to int. And so on.

Indeed, that solved nothing. You seem to have successfully avoided dynamic memory management, so the next step was to search for buffer overflow. Fortunately gcc has some helpful options: -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC. (Just discovered them.) I will have to research them additionally, but among other things they add indexing bounds checks for the vector containers. And, as expected, index out of bounds, namely a negative one showed up.

I caught the negative index in the void Poblacion :: Mutacion (Individuo &), in the line:
 
		ind.parametros_reales[k - prob_booleano - 1] = parametro;

To catch it yourself, I suggest you compile with the fore-mentioned options (-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC). Next, what I did (I don't know if this is the right approach) is to define the function:
1
2
3
void myabort (int) {
    cerr << "abort handler called\n";
}
just before int main () and inserted the code:
 
    signal(SIGABRT, myabort);
right after the beginning of main. This is necessary, because it allows you to set breakpoint in myabort. The index checks are probably assert-ed and abort is called. I do this for the first time, so there may be better ways. You will need to include <csignal> in order to use the signal function.

The issue is probably missing initialization. I have not investigated it further.

Here are the values of the locals in void Poblacion :: Mutacion (Individuo &) when the situation occurs:
	k	0
	parametro	0.0304727331
	prob_booleano	7
	prob_total	86
Hey, I've not understood it at all, but I've found one possible error in Poblacion :: Mutacion. I had:

if ((0 <= prob_total) && (prob_total < prob_booleano))

Instead of:

if ((0 <= k) && (k < prob_booleano))

But all the things you say with signals I don't understand them at all... You means that the programs crashes at Poblacion :: Mutation?

Last edited on
Yes, this may be the error.

In the code in void Poblacion :: Mutacion (Individuo &), in the line:
 
		ind.parametros_reales[k - prob_booleano - 1] = parametro;
the index expression "k - prob_booleano - 1" sometimes ends up being negative.

The values of the local variables in one such situation (that I actually observed) were:
	k	0
	parametro	0.0304727331
	prob_booleano	7
	prob_total	86
As you can see yourself, in this case, the value of "k - prob_booleano - 1" is -8, which is an invalid index.

EDIT: The index will be valid if "k >=prob_booleano + 1". I can not say whether this is consistent with the rationale of your application.
Last edited on
Now, I've edited the function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// El numero generado cae dentro de los parametros booleanos
	if ((0 <= k) && (k < prob_booleano))
	{
		if (ind.operacion_escalar[k] == 0)
			ind.operacion_escalar[k] = 1;
		
		if (ind.operacion_escalar[k] == 1)
			ind.operacion_escalar[k] = 0;
	}
	
	// El numero generado cae dentro de los reales
	else if (k > prob_booleano)
	{
		float parametro = ind.Numeros_Aleatorios_Entre_a_y_b (ind.limite_inferior,
		 																	 	ind.limite_superior);
		
		ind.parametros_reales[k - prob_booleano - 1] = parametro;
		
	}


Now i think that k - prob_booleano - 1 can't be negative because k at least is prob_booleano + 1

Could this be the root of all problems?

Many Thanks again


----

EDIT: I've executed my code again some few times, but problems persists: the infinite loop ?? in
Poblacion :: Ruleta and the same result returned ?? in Poblacion :: K_Torneo
Last edited on
Yes, the program still hangs sporadically. I suspect some buffer overflow/stack smashing somewhere that causes the code to behave like so. But I don't know how to detect it.
Ok, worked a bit more on this. It seems that the loop in Ruleta() sometimes terminates without finding whatever it is supposed to find. I mean this loop exits from below sometimes:
1
2
3
4
5
6
7
8
9
10
for (int i = 0; i < (int)fitness_aux.size(); i++)
{
	contador += fitness_aux[i];
		
	if (contador >= aleatorio)
	{
		return i;
	}
		
}

So, the end of the Ruleta() function (which had no return statement in the end) is actually reached. I found this because I put a return 0 there and as a consequence the loop in Algoritmo::Algoritmo(..) did lock up:
1
2
3
4
while (father1 == father2)
{
	father2 = hominum.Ruleta();
}


Should it be possible for the Ruleta() loop to terminate without causing return from inside its body. If it shouldn't, you must make some modifications there. If it should, you must decide what randomized value must be returned before the final brace of the Ruleta() function.

Then.. we'll see...
mmm Where i've got to make the modifications? In Ruleta or Algoritmo? English it's not my native language.. but I (think) have understood that the loop is in Algoritmo and that Ruleta always ends... Anyway, I think it's not possible that RUleta terminates whitout causing return from inside.. so what modifications should I do?

simeonz, I've got to thanks you a ver much, one more time....
If you suspect bad indexing into vectors, You don't you replace all your [] operations with at()? That will throw when you have a problem. You just need to insert suitable error detection.
The problem is in the loop in Ruleta().

I'll explain the exact situation. Here is the loop in Ruleta().
1
2
3
4
5
6
7
8
9
10
11
for (int i = 0; i < (int)fitness_aux.size(); i++)
{
	contador += fitness_aux[i];
		
	if (contador >= aleatorio)
	{
		return i; //point A
	}
		
}
//point B 
And here is the one in Algoritmo(..).
1
2
3
4
5
6
7
8
9
// Seleccion por ruleta	
father1 = hominum.Ruleta(); //point C1
father2 = hominum.Ruleta(); //point C2
father_m = hominum.Ruleta();
// Comprobacion de que los individuos padre son distintos
while (father1 == father2) //point D
{
	father2 = hominum.Ruleta(); //point C3
}

I reverted to your original sources (without my modifications) and reproduced the problem again. You can reproduce it too if you seed the random generator with the value 1649856953.

Here is the story:
1) point A in the loop in Ruleta() is never executed, because the condition guarding it (contador >= aleatorio) is never satisfied.
2) As a consequence the loop terminates from the condition i < (int)fitness_aux.size() and then point B is reached.
3) point B is the end of the Ruleta() function, but there is no return statement there and as a consequence the function returns arbitrary junk.
4) At point Cx (x=1,2,3) the junk returned from Ruleta() is stored in father1 and father2.
5) For technical reasons, that are beyond my understanding, but are also irrelevant, Ruleta() returns the same junk every time. Consequently, father1 and father2 are set to the same values (at point C1 and point C2) and father2 is reassigned with the same value inside the loop (at point C3).
6) Consequently, the condition father1 == father2 remains forever true and the loop never terminates.

Again, as I said, you can reproduce the situation by feeding the value 1649856953 to srand in main.

I learned a lesson. It is not important that you have return statements in all possible control paths, but it is important that you have assert(false) in the control paths that you expect will be never executed. And not that I want to be preachy, but if I may advise you to use such assertions yourself in the future. Yeah, that sounded preachy :)

Regards
kbw wrote:
If you suspect bad indexing into vectors, You don't you replace all your [] operations with at()? That will throw when you have a problem. You just need to insert suitable error detection.

Supposedly, the defines _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC for gcc do that automatically. They even do other stuff. But there are places where arrays may still be used, not only at Phass's code, but at library code. And I thought that some of that code may do something rotten if given inappropriate arguments or something and write over the neighboring stack frames.

EDIT: I found the following options to facilitate error discovery:
-D_GLIBCXX_DEBUG
-D_GLIBCXX_DEBUG_PEDANTIC
-D_FORTIFY_SOURCE=2
-fstack-protector-all
-ftrapv
-fbounds-check
-Wformat-security
and the library option for the linker:
-lssp
But using them was not a very smooth experience.
Last edited on
No they don't. at() throws an exception if the index is out of bounds, so there isn't actually an invalid access, but you get notified in the program when the error has occurred. It's not a postmortem mechanism, but a runtime feature under program control.
kbw, you are right, but do you think that was the point? I was not going to recode Phass's solution with new error reporting mechanism. If that was the purpose, then indeed _GLIBCXX_DEBUG and _GLIBCXX_DEBUG_PEDANTIC, as their name suggests, wouldn't serve as substitute. But for debugging purposes, using those options is IMHO even better than performing mass replace with something. I also can't understand, why don't all compilers produce entirely checked (i.e. fulfill or die like) debug builds by default.

Regards

EDIT: Looking back at what I wrote, I indeed used improper wording. The options do not "do that", they fulfill the same purpose in this case.
Last edited on
Simeonz, but I think that "aleatorio" can't get these high values, because it's generated in a range between [0, F_Aux], so I don't understand it at all... I think that contador will always reach the aleatorio value

(I'm not in my flat this weekend so I can't see my code, but I think that this value is in the range

Thanks again)
Sorry. Not from where I am standing.
Here are the values of the local variables before the loop in Ruleta():
	F	inf
	F_aux	-nan(0x400000)
	aleatorio	-nan(0x400000)
	contador	0
	fitness_aux	<100 items>
		[0]	inf
                ...
		[47]	inf
		[48]	-nan(0x400000)
		[49]	inf
                ...
		[99]	inf
	i	100
	this	
		population	<100 items>

As I said, it would be best if you try reproduce it yourself with the seed that I gave you. Apparently there is a deeper cause for the problem, but since it happens in the first iteration of the main loop in Algoritmo, I hope it should not be very hard to debug it.

Regards
Last edited on
the problem might be the compiler and issues between a bool and a pointer... for your init don't put a zero just a ";" and see what happens


Change:
1
2
	vector<bool> mascara_booleana (0);
	vector<bool> mascara_reales (0);


to
1
2
	vector<bool> mascara_booleana;
	vector<bool> mascara_reales;


I think that it might be confusion with the zeros being, bools, pointers, or sizes... see if that works...
alternatively, you could cast them as size_type if that what they are... plus, if the push functions take pointers, you may have to change all the 0,1 to false, true or cast as bool.. I could be wrong about it all though..., but worth a shot if it hasn't been fixed already..
Hi guys, I arrived home now so I can work on my code again.

Simeonz, I don't understand you: why have I to try that with this seed value, if "aletorio" is generated in a range?

craniumonempty, so... I've to change "0" & "1" into false & trues?

Be patient with me, my english is not perfect and I don't understand you sometimes... :(

Thanks
Pages: 1234