Go Down

Topic: modify freeRam() to find fragmentation (Read 10395 times) previous topic - next topic

Thomas499

#30
Dec 17, 2015, 09:06 pm Last Edit: Dec 17, 2015, 09:07 pm by Thomas499
Quote
not to hang crepe, but wouldn't the Observer Effect apply here?

The mere presence of the overhead of the library you are working would affect the results, no?
It would say you have a little smaller Largest FreeRam Space yes. But I could always figure out how much of that space is taken away by using the library and add that number to the number it prints if I wanted to. All I'd have to do is a freeRam() test before the library is called, then another one where it finds the number to print. Find the difference in the two and add that number to the library so that when it prints (LargestFreeRam Space) it adds that number automatically each time.

Here's how it will work. I just need a little help getting it to work
Code: [Select]
void Avrheap::freeListWalk(bool withDump)
{   unsigned int largestFrag=freeListLargest();
     __heap_start,*__brkval;
    int v;
    unsigned int currentUfRam = (((int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval))-freeListSize()/*+InsertAmountOfFreeRamUsedToCallEverythingInClassUpToThisPointHereLater*/); // we change it to current unfragmented ram here // this is basic freeRam() modified
    int elements = freeListCount();
    Serial.print(F("\nLargest RamSpace is "));
    if (currentUfRam>largestFrag) // if largest whole space available is fragmented, then we'll print that that rather than the largest unfragmented space availble.
      Serial.print(currentUfRam);
    else
      Serial.print(largestFrag);
    if (isFragmented())
    {
      Serial.print(F(", fragmented " ));
      Serial.print(((int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval))/currentUfRam); // freeRam()/(freeRam()-freeListSize()
      Serial.print(F("%"));
    }
    else
      Serial.print(F(", clean"));
    Serial.print(F(", count "));
    Serial.print(elements);
    Serial.print(F(", total size "));
    Serial.print(freeListSize());
    Serial.print(F(", largest "));
    Serial.println(largestFrag);

nickgammon

#31
Dec 17, 2015, 10:43 pm Last Edit: Dec 17, 2015, 10:43 pm by Nick Gammon
It's not necessarily bad to have fragmentation. If you allocate fixed-size blocks, and then free them in some random order you will have fragmentation. But next time you need that memory the fragmented part will be used.

The worst-case scenario is usually when people gradually make a String longer, eg.

Code: [Select]
String foo;

...

if (Serial.available ())
  foo += Serial.read ();


This will allocate blocks increasing in size by one each time, so the earlier blocks cannot always be re-used (however, if you allocated 1, 2, 3 bytes) then the "3" could be a combination of the "1" and "2" parts, conceivably.

Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Thomas499

#32
Dec 17, 2015, 10:45 pm Last Edit: Dec 17, 2015, 10:45 pm by Thomas499
This is what I changed in the cpp file of the library
Code: [Select]
void Avrheap::freeListWalk(bool withDump)
{   unsigned int largestFrag=freeListLargest();
     __heap_start,*__brkval;
    int v;
    unsigned int currentUfRam = (((int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval))-freeListSize()/*+InsertAmountOfFreeRamUsedToCallEverythingInClassUpToThisPointHereLater*/); // we change it to current unfragmented ram here // this is basic freeRam() modified
    int elements = freeListCount();
    Serial.print(F("\nLargest RamSpace is "));
    if (currentUfRam>largestFrag) // if largest whole space available is fragmented, then we'll print that that rather than the largest unfragmented space availble.
      Serial.print(currentUfRam);
    else
      Serial.print(largestFrag);
    if (isFragmented())
    {
      Serial.print(F(", fragmented " ));
      Serial.print(((int)&v - (__brkval == 0 ? (int)&__heap_start : (int) __brkval))/currentUfRam); // freeRam()/(freeRam()-freeListSize()
      Serial.print(F("%"));
    }
    else
      Serial.print(F(", clean"));
    Serial.print(F(", count "));
    Serial.print(elements);
    Serial.print(F(", total size "));
    Serial.print(freeListSize());
    Serial.print(F(", largest "));
    Serial.println(largestFrag);


    /*
    if (elements)
    {
        for (struct __freelist* p = __flp; p; p = p->next)
        {
            hWord(Serial, (uint16_t)p);
            Serial.print(F(": size "));
            Serial.print((uint16_t)p->size);
            Serial.print(F(" next "));
            hWord(Serial, (uint16_t)p->next);
            Serial.println();
            if (withDump)
            {
                dumpR(Serial, ((byte*)p)+2, p->size);
                Serial.println();
            }
        }
    }*/
}


This is my main code
Code: [Select]
Avrheap myheap;
unsigned long previousMillis = 1000;
unsigned int interval = 1;
unsigned int number=0;
int *par[10];
String T="";

void setup() {
  Serial.begin(38400);     
}
void loop() {
  unsigned long currentMillis = millis()/1000;
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    number++;
    Serial.print(F("#"));
    Serial.print(number);
    Serial.print(F(" "));
    Serial.print(currentMillis);
    Serial.print(F(" "));
    Serial.println(freeRam());
    //CheckRam();
    T=T+='c';
    Serial.println(T);
    string();
    check2();
    Serial.println(F("================"));
    Serial.println();
    Serial.println();
    Serial.println();
  }
}
  void check2(){
  Serial.println();
  Serial.println(myheap);
  myheap.freeListWalk();
  }


This is what the Serial monitor prints out though....
Code: [Select]
#1 0 1330
c
kkkkkkkkkkkkkkkkkkkkkk
jjjjj

Heap

03BC 2
03BC: 02 00 63 00                                     '..c.'



Largest RamSpace is 1320, clean, count 0, total size 0, largest 0
================



#2 1 1330
cc
kkkkkkkkkkkkkkkkkkkkkk
jjjjj

Heap

03BC 3
03BC: 03 00 63 63 00                                  '..cc.'



Largest RamSpace is 1319, clean, count 0, total size 0, largest 0
================



#3 2 1329
ccc
kkkkkkkkkkkkkkkkkkkkkk
jjjjj

Heap

03BC 4
03BC: 04 00 63 63 63 00                               '..ccc.'



Largest RamSpace is 1318, clean, count 0, total size 0, largest 0
================



#4 3 1328
cccc
kkkkkkkkkkkkkkkkkkkkkk
jjjjj

Heap

03BC 5
03BC: 05 00 63 63 63 63 00                            '..cccc.'



Largest RamSpace is 1317, clean, count 0, total size 0, largest 0
================



#5 4 1327
ccccc
kkkkkkkkkkkkkkkkkkkkkk
jjjjj

Heap

03BC 6
03BC: 06 00 63 63 63 63 63 00                         '..ccccc.'



Largest RamSpace is 1316, clean, count 0, total size 0, largest 0
================



#6 5 1326
cccccc
kkkkkkkkkkkkkkkkkkkkkk
jjjjj

Heap

03BC 7
03BC: 07 00 63 63 63 63 63 63 00                      '..cccccc.'



Largest RamSpace is 1315, clean, count 0, total size 0, largest 0
================


any suggestions for what I am doing wrong?

Thomas499

Quote
It's not necessarily bad to have fragmentation. If you allocate fixed-size blocks, and then free them in some random order you will have fragmentation. But next time you need that memory the fragmented part will be used.

The worst-case scenario is usually when people gradually make a String longer, eg.
If you use the simpleWiFiserver that comes in the preloaded library once you call the server the arduino will run for 12 minutes once you call it, then it will freeze and become unresponsive. I checked for freeRam, and noticed it looked fine even right before the crash happened. I want to be able to use this to help me determine what is causing the crash. If fragmentation is occurring, I would like to be able to see it. I made a really awesome webserver, but I can't use it because it freezes the arduino. I took out all the Strings, but still nothing seems to prevent a freeze.




BulldogLowell

If you use the simpleWiFiserver that comes in the preloaded library once you call the server the arduino will run for 12 minutes once you call it, then it will freeze and become unresponsive. I checked for freeRam, and noticed it looked fine even right before the crash happened. I want to be able to use this to help me determine what is causing the crash. If fragmentation is occurring, I would like to be able to see it. I made a really awesome webserver, but I can't use it because it freezes the arduino. I took out all the Strings, but still nothing seems to prevent a freeze.
maybe you can't see  the forrest for the trees... have you had any feedback on your code from the forum?

Some keen eyes here may be able to find your memory leak, if that's the cause.

nickgammon

I made a web server for the Arduino: http://www.gammon.com.au/forum/?id=12942

Because memory is tight (in general) it does not use the String class or dynamic memory allocation at all. Maybe that will help.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

nickgammon

This is starting to sound like an X-Y problem.

http://xyproblem.info/

How about posting the code which hangs after 12 minutes?

Quote
If you use the simpleWiFiserver that comes in the preloaded library ...
Just post your code. We don't know what library, what version of the IDE, etc.
Please post technical questions on the forum, not by personal message. Thanks!

More info: http://www.gammon.com.au/electronics

Thomas499

Quote
maybe you can't see  the forrest for the trees... have you had any feedback on your code from the forum?

Some keen eyes here may be able to find your memory leak, if that's the cause.
Yes, Heres the thread a lot of people mentioned the WiFi shield had all kind of problems and that's why it was retired. I switched to Ethernet and now it doesn't freeze. I'm past looking for a solution because the Ethernet version works fine, but now its more of curiosity to figure out pointers, and to see if I can figure out how to use them to see actual fragmentation in the works.

A lot of people build tic tac toe games and such to see if they actually understand enough to make it work. I wanted to test my skills and learn at the same time by building the fragmentation identifier.


Quote
This is starting to sound like an X-Y problem.

http://xyproblem.info/

How about posting the code which hangs after 12 minutes?
See thread link up top, but even the simple wifi webserver code that comes pre installed in the library will freeze sometime in between 12 minutes to 10 hours once the server is called.



Thomas499

I think i'm getting the hang out understanding a lot of stuff about this library now. I have two questions right now that would really help me progress through the project.

1. When I try to make fragmentation using String like this
Code: [Select]
  Serial.println(F("\nallocate 10 chunks\n"));
  for (int i = 0; i < 5; i++)                // how the library creates fragmentation
  {
    int mSize = random(1, 40) * sizeof(int);
    par[i] = (int*) malloc(mSize); // all different sizes
    *par[i] = 0;
    dumpAlloced((byte*)par[i], false);
  }
  Serial.println();
  String k = "hello";
  String l = "WTFI"; // how I am trying to create fragmentation
  String p = "omg";
  String t = "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
  myheap.dumpHeap(80);
  Serial.println();
  Serial.println(myheap);
  myheap.freeListWalk();

  Serial.println(F("free 3 pointers"));
  free(par[3]);
  free(par[1]);
  free(par[7]);          // how library creates fragmentation
  //free(par[9]);
  t = "";     // how I am trying to create fragmentation
  p = "";
It doesn't jump from one block of used memory to the next correctly. This is how I am trying to do it but it counts by two each time, rather than by the actual size of the memory block.
Code: [Select]
Serial.println(F("end of followHeap"));
    unsigned int *kp;//myheap.startAddress();
    kp = &__heap_start;
  while ((unsigned long)kp<(2000))
  {
 
  Serial.println((unsigned long)kp); //889
  Serial.println((unsigned long)*kp); // 2
  Serial.println((unsigned long)&kp); // 2284 // address of int kp not the address which kp points to
  //Serial.println((unsigned int)kp->size)
  //Serial.println((unsigned long)*kp->size)
  //Serial.println(&kp->size)
  Serial.println((unsigned long)kp);
  //Serial.println(kp*);
  //Serial.println(kp&);
  Serial.println(sizeof(kp)); //2
//  Serial.println(sizeof(kp*));
//  Serial.println(sizeof(kp&));
  Serial.println(sizeof(*kp));//2
  Serial.println(sizeof(&kp));//2
  Serial.println(*kp);
  kp += (byte) *kp +2;
  Serial.print('\t');
  }
  Serial.print("fragmented: ");
  Serial.println(myheap.isFragmented() ? "True" : "False");
  Serial.print("count: ");
Does the program automatically use malloc when you create a String so it knows how long it is, or do I need to use malloc for this to work?

The second question is how do I use sizeof to determine size of the string? above it is telling me the size of the pointer, i tried several ways, but I want to write it so that it tells me the size of the memory block the pointer is pointing to.

BulldogLowell

Code: [Select]
size_t myStringLength = myString.length();

Thomas499

#40
Dec 19, 2015, 05:04 pm Last Edit: Dec 19, 2015, 05:05 pm by Thomas499
Quote
size_t myStringLength = myString.length();
Just to be clear size_t myStringLength = myString.Length(*PointerHere); ?

I just loaded the example that came with the library without making any changes to it.
To my surprise this is part of what it printed
Code: [Select]

Start C:\Users\Chelsea\Documents\Arduino\libraries\avrheap\examples\heapdemo2\heapdemo2.ino
LibVersion 0.1.04

HEAP ADDR: 01F2

allocate 10 chunks

01F4: size 18
0208: size 44
0236: size 6
023E: size 18
0252: size 30
0272: size 76
02C0: size 54
02F8: size 34
031C: size 70
0364: size 6

08FF RAMEND
08F5 SP
036A __brkval
0000 __malloc_heap_end
01F2 __malloc_heap_start
01F2 __heap_start
01F2 __bss_end
0132 __bss_start
0132 __data_end
0100 __data_start
0080 __malloc_margin

start of heap

01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65 2C 00 00 00 69 65 6E 74 00 48 54 54 '/.ne,...ient.HTT'
0212: 4C 00 00 00 31 20 32 30 30 20 4F 4B 00 43 6F 6E 'L...1 200 OK.Con'
0222: 74 65 6E 74 2D 74 79 70 65 3A 74 65 78 74 2F 68 'tent-type:text/h'
0232: 74 6D 06 00 00 00 69 63 10 00 12 00 00 00 72 65 'tm....ic......re'

Heap

01F2 18
01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65                                     '/.ne'

0206 44
0206: 2C 00 00 00 69 65 6E 74 00 48 54 54 4C 00 00 00 ',...ient.HTTL...'
0216: 31 20 32 30 30 20 4F 4B 00 43 6F 6E 74 65 6E 74 '1 200 OK.Content'
0226: 2D 74 79 70 65 3A 74 65 78 74 2F 68 74 6D       '-type:text/htm'

0234 6
0234: 06 00 00 00 69 63 10 00                         '....ic..'

023C 18
023C: 12 00 00 00 72 65 66 3D 22 2F 48 22 3E 68 65 72 '....ref="/H">her'
024C: 16 00 00 00                                     '....'

0250 30
0250: 1E 00 00 00 72 6E 20 74 68 65 20 4C 45 44 20 6F '....rn the LED o'
0260: 28 00 00 00 26 00 C6 02 6F 6E 3C 62 72 3E 00 43 '(...&.Æ.on<br>.C'

0270 76
0270: 4C 00 00 00 20 3C 61 20 68 72 65 66 3D 22 2F 4C 'L... <a href="/L'
0280: 22 3E 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 '">here</a>..8...'
0290: 74 68 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 'the LED on p.. 9'
02A0: 20 6F 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 ' off<br>.... /H.'
02B0: 47 45 54 20 2F 4C 00 63 6C 69 65 6E 74 20       'GET /L.client '

02BE 54
02BE: 36 00 00 00 10 03 65 63 02 00 00 00 22 00 00 00 '6.....ec...."...'
02CE: 0B 04 4E 6F 20 53 6F 63 6B 65 74 20 61 76 61 69 '..No Socket avai'
02DE: 6C 61 62 6C 65 00 00 00 00 00 61 07 4B 08 E0 07 'lable.....a.K.à.'
02EE: 0C 00 00 00 77 07 D7 08                         '....w.×.'

02F6 34
02F6: 22 00 00 00 87 08 30 00 00 00 00 00 00 00 54 09 '"...‡.0.......T.'
0306: 8E 09 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 'Ž.j.....¼.....W.'
0316: 08 00 00 00                                     '....'

031A 70
031A: 46 00 00 00 28 13 34 00 00 00 61 6E 00 69 6E 66 'F...(.4...an.inf'
032A: 00 6F 76 66 1A 00 00 00 F2 04 2A 00 2A 00 40 04 '.ovf....ò.*.*.@.'
033A: 00 00 00 00 48 04 88 04 A0 04 AA 04 B6 04 00 00 '....H.ˆ. .ª.¶...'
034A: 00 00 00 00 00 00 00 00 2A 00 CE 02 04 03 00 00 '........*.Î.....'
035A: 50 00 00 00 1E 03 00 00                         'P.......'

0362 6
0362: 06 00 00 00 00 00 00 00                         '........'



FreeList: clean, count 0, largest 0, total size 0

free 3 pointers

FreeList: fragmented, count 3, largest 76, total size 134

023C: size 18 next 0270
023E: 70 02 72 65 66 3D 22 2F 48 22 3E 68 65 72 16 00 'p.ref="/H">her..'
024E: 00 00                                           '..'

0270: size 76 next 02F6
0272: F6 02 20 3C 61 20 68 72 65 66 3D 22 2F 4C 22 3E 'ö. <a href="/L">'
0282: 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 74 68 'here</a>..8...th'
0292: 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 20 6F 'e LED on p.. 9 o'
02A2: 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 47 45 'ff<br>.... /H.GE'
02B2: 54 20 2F 4C 00 63 6C 69 65 6E 74 20             'T /L.client '

02F6: size 34 next 0000
02F8: 00 00 87 08 30 00 00 00 00 00 00 00 54 09 8E 09 '..‡.0.......T.Ž.'
0308: 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 08 00 'j.....¼.....W...'
0318: 00 00                                           '..'

1 malloc

FreeList: fragmented, count 3, largest 76, total size 122

023C: size 6 next 0270
023E: 70 02 72 65 66 3D                               'p.ref='

0270: size 76 next 02F6
0272: F6 02 20 3C 61 20 68 72 65 66 3D 22 2F 4C 22 3E 'ö. <a href="/L">'
0282: 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 74 68 'here</a>..8...th'
0292: 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 20 6F 'e LED on p.. 9 o'
02A2: 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 47 45 'ff<br>.... /H.GE'
02B2: 54 20 2F 4C 00 63 6C 69 65 6E 74 20             'T /L.client '

02F6: size 34 next 0000
02F8: 00 00 87 08 30 00 00 00 00 00 00 00 54 09 8E 09 '..‡.0.......T.Ž.'
0308: 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 08 00 'j.....¼.....W...'
0318: 00 00                                           '..'

08FF RAMEND
08F5 SP
036A __brkval
0000 __malloc_heap_end
01F2 __malloc_heap_start
01F2 __heap_start
01F2 __bss_end
0132 __bss_start
0132 __data_end
0100 __data_start
0080 __malloc_margin

start of heap

01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65 2C 00 00 00 69 65 6E 74 00 48 54 54 '/.ne,...ient.HTT'
0212: 4C 00 00 00 31 20 32 30 30 20 4F 4B 00 43 6F 6E 'L...1 200 OK.Con'
0222: 74 65 6E 74 2D 74 79 70 65 3A 74 65 78 74 2F 68 'tent-type:text/h'
0232: 74 6D 06 00 00 00 69 63 10 00 06 00 70 02 72 65 'tm....ic....p.re'

Heap

01F2 18
01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65                                     '/.ne'

0206 44
0206: 2C 00 00 00 69 65 6E 74 00 48 54 54 4C 00 00 00 ',...ient.HTTL...'
0216: 31 20 32 30 30 20 4F 4B 00 43 6F 6E 74 65 6E 74 '1 200 OK.Content'
0226: 2D 74 79 70 65 3A 74 65 78 74 2F 68 74 6D       '-type:text/htm'

0234 6
0234: 06 00 00 00 69 63 10 00                         '....ic..'

023C 6 (free)
023C: 06 00 70 02 72 65 66 3D                         '..p.ref='

0244 10
0244: 0A 00 48 22 3E 68 65 72 16 00 00 00             '..H">her....'

0250 30
0250: 1E 00 00 00 72 6E 20 74 68 65 20 4C 45 44 20 6F '....rn the LED o'
0260: 28 00 00 00 26 00 C6 02 6F 6E 3C 62 72 3E 00 43 '(...&.Æ.on<br>.C'

0270 76 (free)
0270: 4C 00 F6 02 20 3C 61 20 68 72 65 66 3D 22 2F 4C 'L.ö. <a href="/L'
0280: 22 3E 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 '">here</a>..8...'
0290: 74 68 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 'the LED on p.. 9'
02A0: 20 6F 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 ' off<br>.... /H.'
02B0: 47 45 54 20 2F 4C 00 63 6C 69 65 6E 74 20       'GET /L.client '

02BE 54
02BE: 36 00 00 00 10 03 65 63 02 00 00 00 22 00 00 00 '6.....ec...."...'
02CE: 0B 04 4E 6F 20 53 6F 63 6B 65 74 20 61 76 61 69 '..No Socket avai'
02DE: 6C 61 62 6C 65 00 00 00 00 00 61 07 4B 08 E0 07 'lable.....a.K.à.'
02EE: 0C 00 00 00 77 07 D7 08                         '....w.×.'

02F6 34 (free)
02F6: 22 00 00 00 87 08 30 00 00 00 00 00 00 00 54 09 '"...‡.0.......T.'
0306: 8E 09 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 'Ž.j.....¼.....W.'
0316: 08 00 00 00                                     '....'

031A 70
031A: 46 00 00 00 28 13 34 00 00 00 61 6E 00 69 6E 66 'F...(.4...an.inf'
032A: 00 6F 76 66 1A 00 00 00 F2 04 2A 00 2A 00 40 04 '.ovf....ò.*.*.@.'
033A: 00 00 00 00 48 04 88 04 A0 04 AA 04 B6 04 00 00 '....H.ˆ. .ª.¶...'
034A: 00 00 00 00 00 00 00 00 2A 00 CE 02 04 03 00 00 '........*.Î.....'
035A: 50 00 00 00 1E 03 00 00                         'P.......'

0362 6
0362: 06 00 00 00 00 00 00 00                         '........'


done



To the right that http code isn't in the example I loaded. Is it looking at the computers memory instead of the arduinos?

BulldogLowell

#41
Dec 19, 2015, 06:06 pm Last Edit: Dec 19, 2015, 10:22 pm by BulldogLowell
Just to be clear size_t myStringLength = myString.Length(*PointerHere); ?
No.

You can de-reference a pointer to a String like this:

Code: [Select]

size_t myStringLength = (*myPtrToString).length();


or like this:
Code: [Select]

size_t myStringLength = myPtrToString->length();





robtillaart

Just to be clear size_t myStringLength = myString.Length(*PointerHere); ?

I just loaded the example that came with the library without making any changes to it.
To my surprise this is part of what it printed
Code: [Select]

Start C:\Users\Chelsea\Documents\Arduino\libraries\avrheap\examples\heapdemo2\heapdemo2.ino
LibVersion 0.1.04

HEAP ADDR: 01F2

allocate 10 chunks

01F4: size 18
0208: size 44
0236: size 6
023E: size 18
0252: size 30
0272: size 76
02C0: size 54
02F8: size 34
031C: size 70
0364: size 6

08FF RAMEND
08F5 SP
036A __brkval
0000 __malloc_heap_end
01F2 __malloc_heap_start
01F2 __heap_start
01F2 __bss_end
0132 __bss_start
0132 __data_end
0100 __data_start
0080 __malloc_margin

start of heap

01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65 2C 00 00 00 69 65 6E 74 00 48 54 54 '/.ne,...ient.HTT'
0212: 4C 00 00 00 31 20 32 30 30 20 4F 4B 00 43 6F 6E 'L...1 200 OK.Con'
0222: 74 65 6E 74 2D 74 79 70 65 3A 74 65 78 74 2F 68 'tent-type:text/h'
0232: 74 6D 06 00 00 00 69 63 10 00 12 00 00 00 72 65 'tm....ic......re'

Heap

01F2 18
01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65                                     '/.ne'

0206 44
0206: 2C 00 00 00 69 65 6E 74 00 48 54 54 4C 00 00 00 ',...ient.HTTL...'
0216: 31 20 32 30 30 20 4F 4B 00 43 6F 6E 74 65 6E 74 '1 200 OK.Content'
0226: 2D 74 79 70 65 3A 74 65 78 74 2F 68 74 6D       '-type:text/htm'

0234 6
0234: 06 00 00 00 69 63 10 00                         '....ic..'

023C 18
023C: 12 00 00 00 72 65 66 3D 22 2F 48 22 3E 68 65 72 '....ref="/H">her'
024C: 16 00 00 00                                     '....'

0250 30
0250: 1E 00 00 00 72 6E 20 74 68 65 20 4C 45 44 20 6F '....rn the LED o'
0260: 28 00 00 00 26 00 C6 02 6F 6E 3C 62 72 3E 00 43 '(...&.Æ.on<br>.C'

0270 76
0270: 4C 00 00 00 20 3C 61 20 68 72 65 66 3D 22 2F 4C 'L... <a href="/L'
0280: 22 3E 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 '">here</a>..8...'
0290: 74 68 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 'the LED on p.. 9'
02A0: 20 6F 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 ' off<br>.... /H.'
02B0: 47 45 54 20 2F 4C 00 63 6C 69 65 6E 74 20       'GET /L.client '

02BE 54
02BE: 36 00 00 00 10 03 65 63 02 00 00 00 22 00 00 00 '6.....ec...."...'
02CE: 0B 04 4E 6F 20 53 6F 63 6B 65 74 20 61 76 61 69 '..No Socket avai'
02DE: 6C 61 62 6C 65 00 00 00 00 00 61 07 4B 08 E0 07 'lable.....a.K.à.'
02EE: 0C 00 00 00 77 07 D7 08                         '....w.×.'

02F6 34
02F6: 22 00 00 00 87 08 30 00 00 00 00 00 00 00 54 09 '"...‡.0.......T.'
0306: 8E 09 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 'Ž.j.....¼.....W.'
0316: 08 00 00 00                                     '....'

031A 70
031A: 46 00 00 00 28 13 34 00 00 00 61 6E 00 69 6E 66 'F...(.4...an.inf'
032A: 00 6F 76 66 1A 00 00 00 F2 04 2A 00 2A 00 40 04 '.ovf....ò.*.*.@.'
033A: 00 00 00 00 48 04 88 04 A0 04 AA 04 B6 04 00 00 '....H.ˆ. .ª.¶...'
034A: 00 00 00 00 00 00 00 00 2A 00 CE 02 04 03 00 00 '........*.Î.....'
035A: 50 00 00 00 1E 03 00 00                         'P.......'

0362 6
0362: 06 00 00 00 00 00 00 00                         '........'



FreeList: clean, count 0, largest 0, total size 0

free 3 pointers

FreeList: fragmented, count 3, largest 76, total size 134

023C: size 18 next 0270
023E: 70 02 72 65 66 3D 22 2F 48 22 3E 68 65 72 16 00 'p.ref="/H">her..'
024E: 00 00                                           '..'

0270: size 76 next 02F6
0272: F6 02 20 3C 61 20 68 72 65 66 3D 22 2F 4C 22 3E 'ö. <a href="/L">'
0282: 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 74 68 'here</a>..8...th'
0292: 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 20 6F 'e LED on p.. 9 o'
02A2: 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 47 45 'ff<br>.... /H.GE'
02B2: 54 20 2F 4C 00 63 6C 69 65 6E 74 20             'T /L.client '

02F6: size 34 next 0000
02F8: 00 00 87 08 30 00 00 00 00 00 00 00 54 09 8E 09 '..‡.0.......T.Ž.'
0308: 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 08 00 'j.....¼.....W...'
0318: 00 00                                           '..'

1 malloc

FreeList: fragmented, count 3, largest 76, total size 122

023C: size 6 next 0270
023E: 70 02 72 65 66 3D                               'p.ref='

0270: size 76 next 02F6
0272: F6 02 20 3C 61 20 68 72 65 66 3D 22 2F 4C 22 3E 'ö. <a href="/L">'
0282: 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 74 68 'here</a>..8...th'
0292: 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 20 6F 'e LED on p.. 9 o'
02A2: 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 47 45 'ff<br>.... /H.GE'
02B2: 54 20 2F 4C 00 63 6C 69 65 6E 74 20             'T /L.client '

02F6: size 34 next 0000
02F8: 00 00 87 08 30 00 00 00 00 00 00 00 54 09 8E 09 '..‡.0.......T.Ž.'
0308: 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 08 00 'j.....¼.....W...'
0318: 00 00                                           '..'

08FF RAMEND
08F5 SP
036A __brkval
0000 __malloc_heap_end
01F2 __malloc_heap_start
01F2 __heap_start
01F2 __bss_end
0132 __bss_start
0132 __data_end
0100 __data_start
0080 __malloc_margin

start of heap

01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65 2C 00 00 00 69 65 6E 74 00 48 54 54 '/.ne,...ient.HTT'
0212: 4C 00 00 00 31 20 32 30 30 20 4F 4B 00 43 6F 6E 'L...1 200 OK.Con'
0222: 74 65 6E 74 2D 74 79 70 65 3A 74 65 78 74 2F 68 'tent-type:text/h'
0232: 74 6D 06 00 00 00 69 63 10 00 06 00 70 02 72 65 'tm....ic....p.re'

Heap

01F2 18
01F2: 12 00 00 00 65 72 20 74 6F 20 68 74 74 70 3A 2F '....er to http:/'
0202: 2F 00 6E 65                                     '/.ne'

0206 44
0206: 2C 00 00 00 69 65 6E 74 00 48 54 54 4C 00 00 00 ',...ient.HTTL...'
0216: 31 20 32 30 30 20 4F 4B 00 43 6F 6E 74 65 6E 74 '1 200 OK.Content'
0226: 2D 74 79 70 65 3A 74 65 78 74 2F 68 74 6D       '-type:text/htm'

0234 6
0234: 06 00 00 00 69 63 10 00                         '....ic..'

023C 6 (free)
023C: 06 00 70 02 72 65 66 3D                         '..p.ref='

0244 10
0244: 0A 00 48 22 3E 68 65 72 16 00 00 00             '..H">her....'

0250 30
0250: 1E 00 00 00 72 6E 20 74 68 65 20 4C 45 44 20 6F '....rn the LED o'
0260: 28 00 00 00 26 00 C6 02 6F 6E 3C 62 72 3E 00 43 '(...&.Æ.on<br>.C'

0270 76 (free)
0270: 4C 00 F6 02 20 3C 61 20 68 72 65 66 3D 22 2F 4C 'L.ö. <a href="/L'
0280: 22 3E 68 65 72 65 3C 2F 61 3E 10 00 38 00 00 00 '">here</a>..8...'
0290: 74 68 65 20 4C 45 44 20 6F 6E 20 70 0A 00 20 39 'the LED on p.. 9'
02A0: 20 6F 66 66 3C 62 72 3E 16 00 00 00 20 2F 48 00 ' off<br>.... /H.'
02B0: 47 45 54 20 2F 4C 00 63 6C 69 65 6E 74 20       'GET /L.client '

02BE 54
02BE: 36 00 00 00 10 03 65 63 02 00 00 00 22 00 00 00 '6.....ec...."...'
02CE: 0B 04 4E 6F 20 53 6F 63 6B 65 74 20 61 76 61 69 '..No Socket avai'
02DE: 6C 61 62 6C 65 00 00 00 00 00 61 07 4B 08 E0 07 'lable.....a.K.à.'
02EE: 0C 00 00 00 77 07 D7 08                         '....w.×.'

02F6 34 (free)
02F6: 22 00 00 00 87 08 30 00 00 00 00 00 00 00 54 09 '"...‡.0.......T.'
0306: 8E 09 6A 09 00 00 00 00 BC 11 04 00 00 00 57 11 'Ž.j.....¼.....W.'
0316: 08 00 00 00                                     '....'

031A 70
031A: 46 00 00 00 28 13 34 00 00 00 61 6E 00 69 6E 66 'F...(.4...an.inf'
032A: 00 6F 76 66 1A 00 00 00 F2 04 2A 00 2A 00 40 04 '.ovf....ò.*.*.@.'
033A: 00 00 00 00 48 04 88 04 A0 04 AA 04 B6 04 00 00 '....H.ˆ. .ª.¶...'
034A: 00 00 00 00 00 00 00 00 2A 00 CE 02 04 03 00 00 '........*.Î.....'
035A: 50 00 00 00 1E 03 00 00                         'P.......'

0362 6
0362: 06 00 00 00 00 00 00 00                         '........'


done



To the right that http code isn't in the example I loaded. Is it looking at the computers memory instead of the arduinos?
it can be part of a previous sketch ...
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Thomas499

#43
Dec 21, 2015, 12:02 am Last Edit: Dec 21, 2015, 12:11 am by Thomas499
You are correct. Apparently when a sketch is loaded it doesn't automatically reset the unused memory back to default.

I'm having a hard time understanding why my math isn't adding up.
I wrote this code to try to help me understand how the memory is split up in the arduino.
Code: [Select]
struct __freelist 
{
    size_t size;
    struct __freelist *next;
};

extern struct   __freelist *__flp;
extern uint16_t __heap_start;
extern uint16_t *__brkval;
extern char     *__malloc_heap_start;
extern char     *__malloc_heap_end;
extern size_t   __malloc_margin;
extern uint16_t __data_start;
extern uint16_t __data_end;
extern uint16_t __bss_start;
extern uint16_t __bss_end;

int loopCount=0;
int ByteCheck=-3;
int Address[4];

void setup()
{
  Serial.begin(115200);
  Serial.println(F("Setup here"));
  start(); // print out at top of serial monitor known memory location start/end values
  Pointer(); // run experimental code
  }
void loop() {}

void Pointer()
{ // ===================== Print Header stuff ===================
  Serial.println(F("Pointer here"));
  char StartingChar = 'C';
  char *PointerofStartingChar=&StartingChar;
  Serial.print(F("\t&StartingChar is "));
  Serial.print((uint16_t)&StartingChar);
  Serial.println(F("PointerofStartingChar is "));
  Serial.print((uint16_t)PointerofStartingChar);
  Serial.print(F("&PointerofStartingChar is "));
  Serial.println((uint16_t)&PointerofStartingChar);
  Serial.print(F("*PointerofStartingChar is "));
  Serial.println(*PointerofStartingChar); // dereferencing // prints value of what pointer points to
  Serial.print(F("size of PointerofStartingChar is "));
  Serial.println(sizeof(*PointerofStartingChar));
  //=================== Start ========================
  while ((int)PointerofStartingChar<500000) // print address's for a while. Picked a large number
  {
    Serial.print(*PointerofStartingChar);
    Serial.print("\tDec is ");
    Serial.print((long)*PointerofStartingChar);
    Serial.print("\tadd is ");
    Serial.println((uint16_t)PointerofStartingChar);
   // ========== Print these when we reach a new point in the memory ==============
    if((uint16_t)PointerofStartingChar==__malloc_margin)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of malloc_margin"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==__data_start)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of data start"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==__data_end)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of data end"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==(uint16_t)&__malloc_heap_start)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of malloc_heap_start"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==(uint16_t)&__malloc_heap_end)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of malloc_heap_end"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==(uint16_t)&__brkval)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of brkval"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==SP)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of SP"));
      Serial.println();
    }
    else if((uint16_t)PointerofStartingChar==RAMEND)
    {
      Serial.println();
      Serial.println((uint16_t)PointerofStartingChar);
      Serial.println(F("reach point of RAMEND"));
      Serial.println();
    } // ==== look for saved values that we are looking for to identify size of memory =======
    if(ByteCheck == 2)
    {
      if((long)*PointerofStartingChar==Address[2])// this number changes when you add a line of code. Must a pointer reference to an address or something
      {
        Serial.print(F("Total bytes used to completely loop are "));
        Serial.println(((long)PointerofStartingChar)-((long)&PointerofStartingChar)-3);
        Serial.print(F("calculated by "));
        Serial.print((long)PointerofStartingChar);
        Serial.print(F("-"));
        Serial.print((long)&StartingChar);
        Serial.println(F("-3"));
        Serial.println(F("We took away three because we went the entire loop, then we went three more bytes to make sure it was the same as the starting point"));
        break;
      }
      else
      ByteCheck=0;
    }
    else if(ByteCheck == 1)
    {
      if((long)*PointerofStartingChar==Address[1])// this changed when i took out the three was 1
      ByteCheck=2;
      else
      ByteCheck=0;
    }
    else if(ByteCheck == 0)
    {
      if((long)*PointerofStartingChar==Address[0])// this changed when i took out the three was 1
      ByteCheck=1;
    }
   /* ====== When first starting, look for address of C and save the next two values that we will look for in the above to confirm beyond reasonable doubt it is the same point ========= */
    else if (ByteCheck==-1) // store reading for check when ByteCheck==2
    { Address[2]=((long)*PointerofStartingChar);
      ByteCheck=0;
      Serial.print(F("Address[2] is "));
      Serial.println(Address[2]);
    }
    else if (ByteCheck==-2) // store reading for check when ByteCheck==1
    {
      Address[1]=((long)*PointerofStartingChar);
      ByteCheck=-1;
      Serial.print(F("Address[1] is "));
      Serial.println(Address[1]);
    }
    else if((long)*PointerofStartingChar=='C')
    {
      if (ByteCheck==-3) // store reading for check when ByteCheck==0
      { Address[0]=((long)*PointerofStartingChar);
        ByteCheck=-2;
        Serial.print(F("Address[0] is "));
        Serial.println(Address[0]);
      }
    }
    PointerofStartingChar=PointerofStartingChar+1;
  }
}

  void start() // print the header stuff
{
    Serial.print((uint16_t)RAMEND);
    Serial.println(F(" RAMEND"));
    Serial.print((uint16_t)SP);
    Serial.println(F(" SP"));
    Serial.print((uint16_t)__brkval);
    Serial.println(F(" __brkval"));
    Serial.print((uint16_t)__malloc_heap_end);
    Serial.println(F(" __malloc_heap_end"));
    Serial.print((uint16_t)__malloc_heap_start);
    Serial.println(F(" __malloc_heap_start"));
    Serial.print((uint16_t)&__heap_start);
    Serial.println(F(" __heap_start"));
    Serial.print((uint16_t)&__bss_end);
    Serial.println(F(" __bss_end"));
    Serial.print((uint16_t)&__bss_start);
    Serial.println(F(" __bss_start"));
    Serial.print((uint16_t)&__data_end);
    Serial.println(F(" __data_end"));
    Serial.print((uint16_t)&__data_start);
    Serial.println(F(" __data_start"));
    Serial.print((uint16_t)__malloc_margin);
    Serial.println(F(" __malloc_margin"));
    Serial.println();
    Serial.println(F("start of heap"));
    Serial.println();
}
It stores a char, and finds the address where the char is located, then it saves the next 3 address contents and runs the entire sketch looking for those values to show up in the same order. This works fine. However, This is where the Serial monitor beings.
Quote
Setup here
2303 RAMEND
2297 SP
0 __brkval
0 __malloc_heap_end
494 __malloc_heap_start
494 __heap_start
494 __bss_end
316 __bss_start
316 __data_end
256 __data_start
128 __malloc_margin

start of heap

Pointer here
   &StartingChar is 2283PointerofStartingChar is
2283&PointerofStartingChar is 2281
*PointerofStartingChar is C
size of PointerofStartingChar is 1
C   Dec is 67   add is 2283
Address[0] is 67
   Dec is 3   add is 2284
Address[1] is 3
^   Dec is 94   add is 2285
Address[2] is 94
The is where the Serial ends
Quote
é   Dec is -23   add is 6377
   Dec is 24   add is 6378
C   Dec is 67   add is 6379
   Dec is 3   add is 6380
^   Dec is 94   add is 6381
Total bytes used to completely loop are 4097
calculated by 6381-2283-3
We took away three because we went the entire loop, then we went three more bytes to make sure it was the same as the starting point
which tells me the entire sketch should be 4097 bytes...

But the IDE says it should be 4,710 bytes...
Quote
Sketch uses 4,710 bytes (14%) of program storage space. Maximum is 32,256 bytes.
Global variables use 238 bytes (11%) of dynamic memory, leaving 1,810 bytes for local variables. Maximum is 2,048 bytes.
Is there a hidden section within the arduino's memory that you can't access once the program is loaded? If so, what is it called, and where is it located? (example above __heap_start?)

BulldogLowell


Go Up