Go Down

Topic: malloc and free ... yeah again :) (Read 1 time) previous topic - next topic

noonv

does free() works?
my sketch use malloc() and free()
after several iterations it fail :(

what could be?
ma bey its malloc fragmentation?  :-/

so how to win this?   :-?
any ideas?

AlphaBeta

Might we see the code?

(Remember to use the
  • button in the 'post editor')
    :)

noonv

thx :)

i try to use Neuro Net  :)
just apdate it from http://nnfpp.sourceforge.net

my library of NNFpp for Arduino: http://robocraft.ru/files/neuronet/NNFpp.zip
I have problemes with example "and"
Code: [Select]

//////////////////////////////////////////////////////////////////////
//
// and.pde
//
// for test NNFpp purposes
//
//
// noonv                                                RoboCraft.ru
//////////////////////////////////////////////////////////////////////

#include "NNFpp.h"

       float weights[]={
           -3.868201,
2.603633, 2.759537 ,
2.221923,
0.242479, 0.843111 ,
-5.077891,
3.518630, 3.420209 ,
2.098542,
1.713860, 1.024128 ,
-3.447142,
5.275442, -2.022131, 7.489859, -1.423821
           };

float *out, in[2]={0,0};
int Neurons[3] = {2,4,1};
           
void setup()
{
     Serial.begin(9600);
}

void loop()
{
     Serial.println("Start...");
       Serial.println("Logical AND with neural network");    

       NNFpp net(3,Neurons,1,NNF_SIGMA_LOGISTIC,0.6);
       net.LoadWeights(weights);


       Serial.println("\nTest: ");

               in[0] = 0;
               in[1] = 0;
               out = net.Execute(in);
               Serial.print("0 0 -> 0: ");
                       Serial.println(out[0]);

               in[0] = 0;
               in[1] = 1;
               out = net.Execute(in);
               Serial.print("0 1 -> 0: ");
                       Serial.println(out[0]);

               in[0] = 1;
               in[1] = 0;
               out = net.Execute(in);
               Serial.print("0 -> 0: ");
                       Serial.println(out[0]);

               in[0] = 1;
               in[1] = 1;
               out = net.Execute(in);
               Serial.print("1 1 -> 1: ");
                       Serial.println(out[0]);

     //-------------------------
     Serial.println("...end.");
       net.Free();
//      while(1)
//      {}
       delay(1000);
}


after several iterations it fail :(

Spinlock

#3
Sep 14, 2009, 03:32 pm Last Edit: Sep 15, 2009, 03:11 am by Spinlock Reason: 1
Are you positive it is memory allocation that is failing?

memory allocation uses the stack,
[EDIT:  Nope - I was wrong, thanks to AWOL for pointing out my mistake!]

so as soon as the loop stack exits, I can't see how it would be memory fragmentation.  I suspect it is rather a pointer writing outside its allocated memory.

Try moving the declaration of your net object to make it a global variable.  If the same problem exists( such as with Execute ) that would verify a loose pointer, vs a malloc failure.

Oh yeah, you may want to check the malloc returns in the constructor of the class to see if they are returning null.  That may help, too!

AWOL

#4
Sep 14, 2009, 03:48 pm Last Edit: Sep 14, 2009, 03:54 pm by AWOL Reason: 1
Quote
memory allocation uses the stack

That's news.  :o
"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

Spinlock

You are right AWOL.  alloca uses stack, malloc does not.

Sorry, got my fingers going faster than my eyes today for some reason.



noonv

Spinlock
Quote
Try moving the declaration of your net object to make it a global variable.  If the same problem exists( such as with Execute ) that would verify a loose pointer, vs a malloc failure.


yes your right :)

if i use code:
Code: [Select]

#include "NNFpp.h"

       float weights[]={
           -3.868201,
2.603633, 2.759537 ,
2.221923,
0.242479, 0.843111 ,
-5.077891,
3.518630, 3.420209 ,
2.098542,
1.713860, 1.024128 ,
-3.447142,
5.275442, -2.022131, 7.489859, -1.423821
           };

float *out, in[2]={0,0};
int Neurons[3] = {2,4,1};

NNFpp net(3,Neurons,1,NNF_SIGMA_LOGISTIC,0.6);

void setup()
{
     Serial.begin(9600);
       net.LoadWeights(weights);
}

void loop()
{
     Serial.println("Start...");
       Serial.println("Logical AND with neural network");

       Serial.println("\nTest: ");

               in[0] = 0;
               in[1] = 0;
               out = net.Execute(in);
               Serial.print("0 0 -> 0: ");
                       Serial.println(out[0]);

               in[0] = 0;
               in[1] = 1;
               out = net.Execute(in);
               Serial.print("0 1 -> 0: ");
                       Serial.println(out[0]);

               in[0] = 1;
               in[1] = 0;
               out = net.Execute(in);
               Serial.print("0 -> 0: ");
                       Serial.println(out[0]);

               in[0] = 1;
               in[1] = 1;
               out = net.Execute(in);
               Serial.print("1 1 -> 1: ");
                       Serial.println(out[0]);

     //-------------------------
     Serial.println("...end.");
     //  net.Free();
//      while(1)
//      {}
       delay(1000);
}

its work fine.
here only one malloc() after that only execute()  ;)
But if ill try to eatch time malloc new net?  ::)

Spinlock

#7
Sep 14, 2009, 04:57 pm Last Edit: Sep 15, 2009, 04:47 am by Spinlock Reason: 1
One thing I can think of is that you are calling NNFpp::Free() twice, yet NNFpp::Free() doesn't handle it properly.  (You explicitely called it in loop(), and the compiler probably generated the calling of the class's destructor function calling in the loop stack cleanup.)

You may want to set layers=0 in Free and check it on Free()'s entry to ensure you don't attempt to free the pointers in the arrays of pointers, or add a check to see if weight is non-null before starting to free it's array memory.

The part I think is suspect is this in NNFpp::Free():
Code: [Select]
for (i=0;i<layers;i++)
     {
           free(bias[i]);bias[i]=NULL;
           free(value[i]);value[i]=NULL;
           free(delta[i]);delta[i]=NULL;
           if (i)
           {
                 [glow]for (j=0;j<neurons[i];j++)[/glow]
                 [glow]{[/glow]
                       [glow]free(weight[i][j]);weight[i][j]=NULL;[/glow]
                 [glow]}[/glow]
           }
           free(weight[i]);weight[i]=NULL;
     }

noonv

2Spinlock
i see...
may be you right  ;)

ill try:
Code: [Select]

for (i=0;i<layers;i++)
     {
           if(bias[i]){free(bias[i]);bias[i]=NULL;}
           if(value[i]){free(value[i]);value[i]=NULL;}
           if(delta[i]){free(delta[i]);delta[i]=NULL;}
           if (i)
           {
                 for (j=0;j<neurons[i];j++)
                 {
                       if(weight[i][j]){free(weight[i][j]);weight[i][j]=NULL;}
                 }
           }
           if(weight[i]){free(weight[i]);weight[i]=NULL;}
     }

Spinlock

I wouldn't go that direction...

You can't trust the array pointers at that point because the array of those pointers was already freed.  If the memory was re-allocated, the pointers contained in weight may be non-null, even though you explicitely set them to null earlier.

That's why I say it may be better to use the variable layers, and set it to 0 on exit of Free().  The next time in, nothing gets called.  (A better way would be to test if(layers==0) and return right at the entry of Free.)


Looks like a cool project though.  I was thinking of pulling out some of my c# neural network classes...


noonv

2Spinlock
thanks :)
I understand - just use the flag of Free  8-)

its not so many RAM to use more usable (and complex  ::) ) Neuro Net :(

Go Up