Forum: Compiler & IDEs ARM: malloc & Null pointer Vergleich


von alexatmk (Gast)


Lesenswert?

Hallo,
bei meinen AVR's hab ich den freien sram immer so getestet:
1
void sramtest(){
2
  //allocates memory up to null pointer
3
  uint16_t i;
4
  uint8_t *sram;
5
6
  for(i=1;i<65500;i++){
7
    if((sram = (uint8_t *) malloc(i*sizeof(uint8_t))) == (void *) 0) {
8
      free(sram);
9
      lcd_string_P("free bytes: ");
10
      lcd_writei(i-1);
11
      i=65500;
12
    }
13
    else{
14
      free(sram);
15
    }
16
17
  }//for

beim ARM (at91sam7s64) funktioniert das nicht.
ich habe auch schon sowas probiert:
1
if((sram = (uint8_t *) malloc(i*sizeof(uint8_t))) == (uint8_t *) 0)


aber die abfrage wird nie .true.

was muss ich beim arm anders machen?

danke
alex

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

== 0 oder == NULL ist beim Vergleich von Zeigern ausreichend, der Cast 
ist überflüssig. Aber: woher soll malloc wissen, wie groß der Heap 
werden darf? Das ist erst dem Linker bekannt.

von alexatmk (Gast)


Lesenswert?

"Aber: woher soll malloc wissen, wie groß der Heap
werden darf? Das ist erst dem Linker bekannt."

es geht ja hier um einen laufzeittest. wie geschrieben, bei den avr's 
erhält man einen Null pointer wenn man versucht mehr als den noch freien 
speicher zu  reservieren. müsste doch beim arm auch gehen. oder habe ich 
was grundsätzliches missverstanden?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Nö, so sollte sich malloc auf allen Plattformen verhalten, auf denen 
eine dynamische Speicherverwaltung implementiert ist.

von Andreas S. (andreas) (Admin) Benutzerseite


Lesenswert?

Trotzdem bleibt die Frage offen: woher soll malloc wissen, ob der 
Speicher reserviert werden kann, oder ob das Ende des Blocks schon 
längst im Stack, potentiellen Stack oder Nirvana liegt?

von Martin Thomas (Gast)


Lesenswert?

Welche libc? Falls newlib: sbrk selbst implementiert? Wenn ja wie? Oder 
sbrk aus libnosys?  Welches Memorylayout (z.B. Data, BSS, Stack, Heap 
oder Data, BSS, Heap, Platz, Stack)?

von alexatmk (Gast)


Lesenswert?

Hallo Martin,

ich verwende die newlib (binutils-2.17, gcc-4.1.1, newlib-1.14.0, 
insight-6.5) und linke arm-elf-4.1.1/arm-elf/lib/redboot-syscalls.o 
dazu. Früher hab ich mal die libnosys verwendet.

Mein linker script sieht so aus:
1
// <h> Memory Configuration
2
//   <h> Code (Read Only)
3
//     <o>  Start <0x0-0xFFFFFFFF>
4
//     <o1> Size  <0x0-0xFFFFFFFF>
5
//   </h>
6
//   <h> Data (Read/Write)
7
//     <o2> Start <0x0-0xFFFFFFFF>
8
//     <o3> Size  <0x0-0xFFFFFFFF>
9
//   </h>
10
//   <h> Top of Stack (Read/Write)
11
//     <o4> STACK <0x0-0xFFFFFFFF>
12
//   </h>
13
// </h>
14
*/
15
16
/* Memory Definitions */
17
18
MEMORY
19
{
20
  CODE (rx) : ORIGIN = 0x00100000, LENGTH = 0x00010000
21
  DATA (rw) : ORIGIN = 0x00200000, LENGTH = 0x00004000
22
  STACK (rw) : ORIGIN = 0x00204000,LENGTH = 0x00000000
23
}
24
25
26
/* Section Definitions */
27
28
SECTIONS
29
{
30
  /* first section is .text which is used for code */
31
  . = 0x0000000;
32
  .text : { *Cstartup.o (.text) }>CODE =0
33
  .text :
34
  {
35
    *(.text)                   /* remaining code */
36
37
    *(.glue_7t) *(.glue_7)
38
39
  } >CODE =0
40
41
  . = ALIGN(4);
42
43
  /* .rodata section which is used for read-only data (constants) */
44
45
  .rodata :
46
  {
47
    *(.rodata)
48
  } >CODE
49
50
  . = ALIGN(4);
51
52
  _etext = . ;
53
  PROVIDE (etext = .);
54
55
  /* .data section which is used for initialized data */
56
57
  .data : AT (_etext)
58
  {
59
    _data = . ;
60
    *(.data)
61
    SORT(CONSTRUCTORS)
62
  } >DATA
63
  . = ALIGN(4);
64
65
  _edata = . ;
66
   PROVIDE (edata = .);
67
68
  /* .bss section which is used for uninitialized data */
69
70
  .bss :
71
  {
72
    __bss_start = . ;
73
    __bss_start__ = . ;
74
    *(.bss)
75
    *(COMMON)
76
  } 
77
  . = ALIGN(4);
78
  __bss_end__ = . ;
79
  __bss_end__ = . ;
80
  _end = .;
81
  PROVIDE (end = .);
82
83
84
   .int_data :  
85
   { 
86
   *(.internal_ram_top) 
87
   }> STACK 
88
89
90
91
  /* Stabs debugging sections.  */


wenn ich das richtig sehe hab ich keinen heap - oder? ich kenn mich mit 
linker scripts überhaupt nicht aus...

Alex





von alexatmk (Gast)


Lesenswert?

ach so,
hätte jemand nen link auf eine vernünftige docu über linker scripts?
danke!

von Rolf Magnus (Gast)


Lesenswert?

Die Doku vom Linker reicht nicht?

von alexatmk (Gast)


Lesenswert?

die scheint gut zu sein, finde sie nur leider nicht in meinen binutils 
(komme mir schon doof vor ;-). ich hab im netz die html seiten gefunden, 
sind halt schlecht zu drucken.
gibts das irgendwo als pdf?

von alexatmk (Gast)


Lesenswert?

ein make ld.pdf hilft, jetzt hab ich's.

von alexatmk (Gast)


Lesenswert?

die funktion mallinfo liefert (zumindest in meinem setup) ganz nüttliche 
informationen. insbesondere arena und uordblks.
ich sehe, daß ich mit malloc immer neuen speicher alloziieren kann, die 
zahl wächst über die eigentliche größe des sram hinaus.
Andreas hat da wohl recht: woher weiß malloc wie weit er gehen darf?
ich hatte gedacht, daß der heap automatisch nach .bss bis top end of 
sram ist. malloc bekommt ja vom 'system' speicher zugewiesen.
nun hatte ich angenommen, daß malloc 'mitgeteilt bekommt', wenn der heap 
ausgeschöpft ist.

wenn ich die docu richtig verstehe, ist es nicht üblich einen heap 
explizit einzurichten - oder?

ich konnte mit meminfo mein memory-leakage finden. mein erstes problem 
ist damit gelöst.

trotzdem würde mich interessieren, ob es eine möglichkeit gibt, den noch 
zu alloziierenden sram zu laufzeit zu ermitteln...










von Martin T. (mthomas) (Moderator) Benutzerseite


Lesenswert?

alexatmk wrote:
> Hallo Martin,

>
1
> ...
2
>   _end = .;
3
>   PROVIDE (end = .);
4
> 
5
> 
6
>    .int_data :
7
>    {
8
>    *(.internal_ram_top)
9
>    }> STACK
10
> 
11
> 
12
> 
13
>   /* Stabs debugging sections.  */
14
> 
15
>
>
>
> wenn ich das richtig sehe hab ich keinen heap - oder? ich kenn mich mit
> linker scripts überhaupt nicht aus...

Layout ist somit .data, .bss, Heap Anfang, Platz für Heap  --->, <--- 
Platz für Stack, Top-Stack. Heap "wächst" zu "grossen" 
Speicheraddressen, Stack "wächst" zu "niedrigen" Speicheraddressen. Out 
of Memory ist also, wenn der Heap-Pointer >= dem Stack-Pointer ist. sbrk 
als syscall für die dynamische Speicherverwaltung "interessiert" sich 
eigentlich erstmal nur dafür wo der Heap anfängt. Üblicherweise durch 
das im  Linkerscript definierte ".end", dem vom Linker ein Wert 
zugewiesen wird. Die sbrk-Implementierung aus 
newlib-Quellcode/libc/sys/arm/syscalls.c zeigt das Prinzip für eine "out 
of memory"-Prüfung ganz anschaulich: wenn aktueller 
Heap-Pointer+angeforderter Speicher > Stack-Pointer -> out of memory. 
Analog kann man die "Lücke" zwischen Heap und Stack errechnen und hat 
damit "available memory". redboot-sbrk hab ich mir bisher nicht 
angeschaut, kann ich also nichts zu sagen.

Hoffe, es bringt ein wenig weiter.
Martin Thomas




Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.