mikrocontroller.net

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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Stefan S. (mexakin)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Sven B. (scummos)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klingt nach Stack Overflow?

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan S. (mexakin)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan S. (mexakin)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan S. (mexakin)
Datum:

Bewertung
0 lesenswert
nicht 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.
SECTIONS
{
    .bss        : {} > RAM | RAM2           /* Global & static vars              */
    .data       : {} > RAM | RAM2           /* Global & static vars              */
    .TI.noinit  : {} > RAM | RAM2           /* For #pragma noinit                */
    .sysmem     : {} > RAM                  /* Dynamic memory allocation area    */
    .stack      : {} > RAM (HIGH)           /* Software system stack             */

#ifndef __LARGE_CODE_MODEL__
    .text       : {} > FLASH                /* Code                              */
#else
    .text       : {} >> FLASH2 | FLASH      /* Code                              */
#endif
    .text:_isr  : {} > FLASH                /* ISR Code space                    */
    .cinit      : {} > FLASH                /* Initialization tables             */
#ifndef __LARGE_DATA_MODEL__
    .const      : {} > FLASH                /* Constant data                     */
#else
    .const      : {} >> FLASH | FLASH2      /* Constant data                     */
#endif
    .cio        : {} > RAM                  /* C I/O Buffer                      */

    .pinit      : {} > FLASH                /* C++ Constructor tables            */
    .binit      : {} > FLASH                /* Boot-time Initialization tables   */
    .init_array : {} > FLASH                /* C++ Constructor tables            */
    .mspabi.exidx : {} > FLASH              /* C++ Constructor tables            */
    .mspabi.extab : {} > FLASH              /* C++ Constructor tables            */
#ifdef __TI_COMPILER_VERSION__
  #if __TI_COMPILER_VERSION__ >= 15009000
    #ifndef __LARGE_CODE_MODEL__
    .TI.ramfunc : {} load=FLASH, run=RAM, table(BINIT)
    #else
    .TI.ramfunc : {} load=FLASH | FLASH2, run=RAM, table(BINIT)
    #endif
  #endif
#endif

Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Stefan S. schrieb:

Der Heap müßte das da sein:

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

Das wird wahrscheinlich von Deiner IDE verwaltet.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.