mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Array gräßer als Speicher? äh


Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo wenn ich in einer Funktion eine array anlegen dann wird sie beim 
Compilieren nicht überprüft.

Beispiel
int main(void)
{
  unsigned char buffer[5000];
  unsigned int i;
  for(i=0; i<5000; i++)
  {
    buffer[i] = SPDR;

  }
  while(1)
  {
  }
}

AVR Memory Usage
----------------
Device: atmega644

Program:     196 bytes (0.3% Full)
(.text + .data + .bootloader)

Data:          0 bytes (0.0% Full)
(.data + .bss + .noinit)

Build succeeded with 0 Warnings...

Dies kann eigentlich nich funktionieren (Mega644 4k Ram).

Wieso spuckt der Compilieren keinen Fehler aus?

//PS
buffer[5000] wird nicht weg Optimiert.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim wrote:

> Wieso spuckt der Compilieren keinen Fehler aus?

Weil ein Compiler nun mal kein Rundumsorglos Packet ist und es im 
Allgemeinen ziemlich schwierig ist, den Speicherverbrauch eines 
Programmes zur Laufzeit vorherzusagen. Was ist dir lieber: Wenn der 
Compiler eine Zahl oder eine Warnung ausspuckt, auf die du dich nicht 
verlassen kannst, oder wenn er dies nicht tut und dich daher zwingt 
selbst zu überlegen was du tust.

Wie gross ist der Speicherverbrauch in folgendem Programm
void foo()
{
  char bar[5000];
}

int main()
{
}

die Allokierung in foo ist völlig irrelevant, da foo ja nie aufgerufen 
wird.

was ist hier?
void foo( int i )
{
  char bar[100];

  if( i == 0 )
    return;

  foo( i - 1 );
}

int main()
{
  foo( 5 );
}

wie gross ist jetzt der Speicherverbrauch zur Laufzeit für lokale 
Variablen?
(Es werden so um die 550 Bytes sein, Stackverbrauch für Returnadressen 
nicht mitgerechnet)
Änderst du den Aufruf in main auf  foo( 100 ), dann wird auch das deinen 
Mega32 sprengen.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ueberlege mal, was fuer ein Aufwand das waere, sowas in gcc einzubauen. 
Die meisten Zielplatformen haben kein festes Speicherlimit, selbst bei 
den AVRs nicht - es gibt ja auch welche, mit externem Speicherinterface. 
Und selbst wenn das nun drin waere, wuerde es nur in den raren, 
offensichtlichen Faellen anschlagen koennen.

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim wrote:

> Wieso spuckt der Compilieren keinen Fehler aus?

Das Array landet auf dem Stack und da prüft der Compiler nicht, ob noch 
genügend Platz vorhanden ist, denn was soll er machen wenn an sich zwar 
genügend Platz im µC ist, aber dieser bereits durch andere Funktionen 
belegt ist (was sich meist erst zur Laufzeit rausstellt)? Er kann nicht 
einfach die Funktion nicht aufrufen.
Eine Möglichkeit wäre ein Stack Overflow Trap (quasi eine Art Interrupt) 
in dem z.B. die Software kontrolliert neu gestartet werden kann.
Solch einer existier auch bei etlichen größeren Controllern und z.B. bei 
den dsPICs. Sowas ist sehr hilfreich bei der Softwareentwicklung.

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mh ok danke

mal noch eine frage

Wenn eine Funktion verlassen wird, wird doch der Speicher für die 
Variablen wieder freigegeben oder?

Kann ich jetzt z.b. 3 Funktionen mit einer Buffer größe von 3000 
anlegen? Oder nur 3 Funktionen mit eine buffer größe von 1000?

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim wrote:

> Wenn eine Funktion verlassen wird, wird doch der Speicher für die
> Variablen wieder freigegeben oder?

Ja.

> Kann ich jetzt z.b. 3 Funktionen mit einer Buffer größe von 3000
> anlegen?

Ja. Allerdings nur wenn die nie gleichzeitig laufen. Die eine darf also 
nicht die andere aufrufen usw.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim wrote:
> mh ok danke
>
> mal noch eine frage
>
> Wenn eine Funktion verlassen wird, wird doch der Speicher für die
> Variablen wieder freigegeben oder?

Richtig.

> Kann ich jetzt z.b. 3 Funktionen mit einer Buffer größe von 3000
> anlegen? Oder nur 3 Funktionen mit eine buffer größe von 1000?

Das kann man so nicht generell sagen.
Das hängt auch davon ab, wie die Aufrufschachtelung ist, welche und 
wieviele Variablen beim Aufrufer angelegt wurden etc.

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke

Wenn ich jetzt dieses Beispiel ausführen würde:

void test1(void)
{
 unsigned char buffer[3000];
}
void test2(void)
{
 unsigned char buffer[3000];
}
int main(void)
{
 test1();
 test2();
}

Dann würde das doch Funktionieren?

Jetzt meine Frage
Beim Compilieren (Linken) werden doch die variablen in Adressen 
aufgelöst? Da müssten ja in test1 und test2 die variablen buffer die 
gleiche adresse haben? Woher weis der Linken das dies Funktionen wie 
verschachtet aufgerufen werden?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim wrote:

> Dann würde das doch Funktionieren?

Kann funktionieren.
Dein Programm benötigt zu keinem Zeitpunkt mehr als etwas über 3000 
Bytes. Du hast 4KB zur Verfügung. Passt also

> Jetzt meine Frage
> Beim Compilieren (Linken) werden doch die variablen in Adressen
> aufgelöst? Da müssten ja in test1 und test2 die variablen buffer die
> gleiche adresse haben? Woher weis der Linken das dies Funktionen wie
> verschachtet aufgerufen werden?

Du missverstehst da etwas. Diese Variablen werden nicht vom Compiler 
erzeugt, sondern sie werden erst zur Laufzeit auf dem Stack erzeugt. 
Daher interessiert sich auch der Compiler bzw. Linker nicht dafür.

Der Ablauf ist so:

* Dein Programm startet. Der Stack ist leer (4KB minus ein paar 
zerquetschte sind frei
* Funktion test1 wird aufgerufen
* Von den vorhendenen 4KB werden 3000 Bytes für buffer abgestellt
* test1 arbeitet
* test1 wird verlassen
* Die Speicherallokierung für buffer wird rückgängig gemacht, der Stack 
ist wieder komplett frei, die 4KB sind wieder völlig frei (minus ein 
paar Zerquetschte für Verwaltungsinfo)
* test2 wird aufgerufen
* Von den vorhandenen 4KB werden 3000 Bytes für eine neue Variable 
buffer bereitgestellt
* test2 arbeitet
* test2 wird verlassen, die Speicherreservierung wird wieder rückgängig 
gemacht.


Zu keinem Zeitpunkt hat dein Programm mehr als die 3000 Bytes in 
Beschlag (minus ein paar Zerquetschte für Verwaltungsinfo)

Autor: Benedikt K. (benedikt) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tim wrote:
> Wenn ich jetzt dieses Beispiel ausführen würde:
> Dann würde das doch Funktionieren?

Ja.

> Beim Compilieren (Linken) werden doch die variablen in Adressen
> aufgelöst?

Nur bei globalen und statischen Variablen.
Lokale Variablen landen zur Laufzeit irgendwo auf dem Stack, je nachdem 
wo gerade der Stackpointer steht.

Beitrag "StackViewer (RAM Rechner) für WinAVR"
Damit kannst du das Ergebnis nachprüfen: Die Software sollte dann 
anzeigen, wieviel RAM der Code tatsächlich belegt.

Autor: Tim (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich Danke euch!! Das hat mir echt weitergeholfen.

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.