Forum: Mikrocontroller und Digitale Elektronik malloc in C notwendig bei lokalen Variablen


von Stefan S. (mexakin)


Lesenswert?

Hallo,

kurze Frage an vlt. jemanden der dasselbe schonmal gemacht hat.

Ich benutze einen MSp430F5659 der sollte an die 66 kB RAM besitzen.
Jetzt habe ich schon ein paar Byte arrays aufgespannt für MEssergebnisse 
alle 16bit array[2048] die ich gerne global hätte, einfach aus Mangel an 
"guten" Programmierkenntnissen so geschehen.

Jetzt wollte ich ein 32bit array[2048] lokal aufgrund einer Berechnung 
hinzufügen und dachte in meiner Naivität ich mach das mal lokal, dann 
holt sich ja der MSP430 einen unbelegten Speicherplatz und benutzt das 
und nach der Funktion wird das wieder freigegeben bzw. kann für andere 
Zwecke benutzt werden.

Das Riesenarray überschreibt mir allerdings Speicherbereiche von anderen 
Variablen, auch globalen Variablen.
Nun befasse ich mich das erste mal mit malloc und soweiter, vielleicht 
hat ja einer eine Pauschalantwort und sagt nein machs mit globalen und 
gut ist.
Platz hab ich ja zum Glück noch frei, wird wohl auf mein nächster 
Versuch sein, daher arbeite ich und vielleicht andere auch gerne mit 
vielen globalen, die kommen sich einfach Gegenseitig nie ins Gehege, 
oder ist das nur meine Sichtweise?

RTOS hab ich nichts am laufen, einfach nur mein eigener Code.

Also Danke schonmal fürs lesen.

Grüße

: Verschoben durch Moderator
von Sven B. (scummos)


Lesenswert?

Klingt nach Stack Overflow?

von Nop (Gast)


Lesenswert?

Stefan S. schrieb:

> Jetzt wollte ich ein 32bit array[2048] lokal aufgrund einer Berechnung
> hinzufügen und dachte in meiner Naivität ich mach das mal lokal, dann
> holt sich ja der MSP430 einen unbelegten Speicherplatz

Tut er auch, aber auf dem Stack - und nicht automatisch via malloc auf 
dem Heap. Zu letzterem müßtest Du malloc schon selber aufrufen. Der 
Stack hat eine statische Größe, die Du irgendwo festlegst, und wenn der 
zu klein für so ein Array ist, hast Du einen Stacküberlauf.

Entweder, Du machst den Stack größer, oder Du läßt es als globale 
Variable. Von malloc würde ich grundsätzlich abraten, sofern es auch 
ohne malloc geht.

von Stefan S. (mexakin)


Lesenswert?

Sven B. schrieb:
> Klingt nach Stack Overflow?

Würd ich zustimmen, aber ich benutzt ja grad mal ein Viertel vom RAM, 
ich test gleich mal wenn ichd as Riesenarray auch als globale definiere.

Was ich nicht verstehe: auf globale Variablen passt mein Compiler, 
CodeComposerStudio8 gut auf, die funktionieren immer miteinander, aber 
was machen die lokalen Variablen, irgendwie scheinen die eben keiner 
Kontrolle zu unterliegen, wobei das ja eigentlich nciht sein kann.

von Nop (Gast)


Lesenswert?

Ach ja, wenn es Dir mehr um halbwegs sauberes Programmieren geht, kannst 
Du das array in der Funktion auch einfach mit "static" deklarieren. Dann 
hast Du es gekapselt, es wird aber nicht auf den Stack gelegt. Es ist 
dann eine globale Variable, die immer ihren Speicher belegt, aber nur 
aus dieser FUnktion heraus ansprechbar ist.

So eine Funktion darfst Du dann aber nicht von verschiedenen Kontexten 
her aufrufen, also nicht z.B. sowohl aus dem Hauptprogramm als auch aus 
einem Interrupt heraus. Oder von verschiedenen Tasks, wenn Du ein RTOS 
hättest.

von Stefan S. (mexakin)


Lesenswert?

Nop schrieb:
..
> Tut er auch, aber auf dem Stack - und nicht automatisch via malloc auf
> dem Heap.

Hammer, danke, die Info hat mir irgendwie gefehlt, ich dachte dass der 
Compiler einfach irgendwie ins Ram schreibt und der stack benutzt wird 
wenn Funktionen aufgerufen werden um pointer etc anzulegen, aber das 
macht ja vollkommen Sinn dass der Stack genau dafür und eben auch für 
die lokalen Variablen genutzt wird.

mein Stack ist 160Bytes groß, kann ich auch umstellen, ich denke aber 
ich lass den so, aus historischern Gründen. Da passen natürlich keine 
2048 Bytes rein.

Was mich jetzt ein wenig wundert, ich kann auch die Heap-size festlegen, 
die wäre 160Bytes aktuell, ich vermute jetzt mal ich benutze den Heap 
niemals, weil ich auf ihn nur mit malloc zugreifen kann, richtig? Das 
Thema war mir irgendwie nie so bewusst, da globale natürlich meistens 
einfach funktionieren oder garnicht funktionieren.

Noch kurz die Frage, mein Stack wächst Rückwärts vom Speicherende in 
meinen "Code" hinein, daher ja auch der Überlauf wenn zu große Daten 
reinlaufen.

Wie kann ich mir den Heap vorstellen, leg ich den vorher fest, oder 
beginnt der immer an der RAM Start adresse?

Danke schonmal.

von Nop (Gast)


Lesenswert?

Stefan S. schrieb:

> mein Stack ist 160Bytes groß

Das erklärt einiges. Oftmals ist die Speicheranordnung so, daß man erst 
die globalen Variablen hat, an noch höheren Adressen den Heap, und 
darüber den Stack. Bei Benutzung wächst der Stack dann nach unten. In 
Deinem Fall wächst der Stack also nicht nur in den Heap, sondern noch 
weiter, und deswegen werden die globalen Variablen überschrieben.

> Was mich jetzt ein wenig wundert, ich kann auch die Heap-size festlegen,
> die wäre 160Bytes aktuell, ich vermute jetzt mal ich benutze den Heap
> niemals, weil ich auf ihn nur mit malloc zugreifen kann, richtig?

Genau. Wobei z.B. printf() hinter den Kulissen u.U. auch noch malloc() 
benutzt.

> Wie kann ich mir den Heap vorstellen, leg ich den vorher fest, oder
> beginnt der immer an der RAM Start adresse?

Der Heap ist letztlich einfach ein Datenbereich, genau wie der Stack. 
Effektiv wird da ein großes Array irgendwo angelegt und dessen 
Anfangsadresse gespeichert.

von Stefan S. (mexakin)


Lesenswert?

Danke NOP.

Jetzt dacht ich ich find den heap auch in meinen files, aber nein.

also Stack ist kein Problem der ist benannt:
aber heap nicht so wirklich, naja vielleicht wird er ja wirklich einfach 
spontan irgendwohingelegt.

Und ja sprintf benutze ich für Fließkommaumwandlungen, von daher wirds 
da schon auch irgendwo drinstecken, hätt ich jetzt fast übersehen, danke 
also.
1
SECTIONS
2
{
3
    .bss        : {} > RAM | RAM2           /* Global & static vars              */
4
    .data       : {} > RAM | RAM2           /* Global & static vars              */
5
    .TI.noinit  : {} > RAM | RAM2           /* For #pragma noinit                */
6
    .sysmem     : {} > RAM                  /* Dynamic memory allocation area    */
7
    .stack      : {} > RAM (HIGH)           /* Software system stack             */
8
9
#ifndef __LARGE_CODE_MODEL__
10
    .text       : {} > FLASH                /* Code                              */
11
#else
12
    .text       : {} >> FLASH2 | FLASH      /* Code                              */
13
#endif
14
    .text:_isr  : {} > FLASH                /* ISR Code space                    */
15
    .cinit      : {} > FLASH                /* Initialization tables             */
16
#ifndef __LARGE_DATA_MODEL__
17
    .const      : {} > FLASH                /* Constant data                     */
18
#else
19
    .const      : {} >> FLASH | FLASH2      /* Constant data                     */
20
#endif
21
    .cio        : {} > RAM                  /* C I/O Buffer                      */
22
23
    .pinit      : {} > FLASH                /* C++ Constructor tables            */
24
    .binit      : {} > FLASH                /* Boot-time Initialization tables   */
25
    .init_array : {} > FLASH                /* C++ Constructor tables            */
26
    .mspabi.exidx : {} > FLASH              /* C++ Constructor tables            */
27
    .mspabi.extab : {} > FLASH              /* C++ Constructor tables            */
28
#ifdef __TI_COMPILER_VERSION__
29
  #if __TI_COMPILER_VERSION__ >= 15009000
30
    #ifndef __LARGE_CODE_MODEL__
31
    .TI.ramfunc : {} load=FLASH, run=RAM, table(BINIT)
32
    #else
33
    .TI.ramfunc : {} load=FLASH | FLASH2, run=RAM, table(BINIT)
34
    #endif
35
  #endif
36
#endif

von Nop (Gast)


Lesenswert?

Stefan S. schrieb:

Der Heap müßte das da sein:

> .sysmem     : {} > RAM                  /* Dynamic memory allocation
> area    */

Das wird wahrscheinlich von Deiner IDE verwaltet.

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.