Forum: Mikrocontroller und Digitale Elektronik Wann reserviert der Compiler speicher für ein Array und wann nicht?


von RAMbuff (Gast)


Lesenswert?

Guten Tag,
ich baue gerade an einem UART rum. Da stellte sich mir die Frage, wie 
der Compiler eigentlich mit Sende- und Empfangsbuffern umgeht.

Wenn ich nun
uart0RxBuf[127];
uart0TxBuf[127];
uart1RxBuf[127];
uart1TxBuf[127];

mache. Kann ich irgendwie dafür sorgen, dass kein halbes kB RAM 
verbraucht wird? Ich könnte z.B. uartTxBuf[127] machen und beide zu 
sendenden UART-Strings darin formen (mache ich mit printf). Meine Frage 
ist, ob der Compiler irgendwie erkennt oder ich ihm sagen kann, dass er 
ruhigen Gewissens beide Variablen an einer Adresse ablegen soll da eh 
immer nur eine in Verwendung ist.

Versteht ihr was ich meine!?
Frohen Nikolaus,
Thorsten

von Peter II (Gast)


Lesenswert?

RAMbuff schrieb:
> Meine Frage
> ist, ob der Compiler irgendwie erkennt oder ich ihm sagen kann, dass er
> ruhigen Gewissens beide Variablen an einer Adresse ablegen soll da eh
> immer nur eine in Verwendung ist.

ja, mit einer Union. Aber warum überhaupt 2 Variablen wenn du immer nur 
eine brauchst?

von dummy (Gast)


Lesenswert?

> Kann ich irgendwie dafür sorgen, dass kein halbes kB RAM
>verbraucht wird?

Schreib das was du nicht benutzt halt nicht hin.

von Dussel (Gast)


Lesenswert?

RAMbuff schrieb:
> Versteht ihr was ich meine!?
Ich nicht. Entweder du brauchst ein Array an, dann legst du ein Array 
an, oder du brauchst zwei, dann kannst du die nicht sinnvoll auf eine 
Adresse legen.

Eventuell könnte Union was für dich sein. Gerade bei Arrays weiß ich 
aber nicht, was das genau macht.
Oder du legst ein Array und einen Zeiger an und lässt den auf das Array 
zeigen.

von RAMbuff (Gast)


Lesenswert?

Dann werde ich nur eine anlegen. Ich brauche nicht zwei. Wollte es nur 
der Ordnung halber. Ich nehme zum Abendessen auch ein anderes Glas als 
zum Frühstück. Gehen würde auch ein einziger Zinnbecher.

von Stefan K. (stefan64)


Lesenswert?

RAMbuff schrieb:
> Dann werde ich nur eine anlegen. Ich brauche nicht zwei. Wollte es nur
> der Ordnung halber. Ich nehme zum Abendessen auch ein anderes Glas als
> zum Frühstück. Gehen würde auch ein einziger Zinnbecher.

Wenn Du es ordentlich haben willst, dann benutze 2 unterschiedliche, 
aber räume sie nach der Benutzung sofort in die Spülmaschine. Dann 
brauchst Du auf Deinem Tisch immer nur Platz für ein Glas.

Gruß, Stefan

von Mike R. (thesealion)


Lesenswert?

Aber im Schrank hast brauchst du dann immer noch Platz für beide Gläser 
(oder in der Spülmaschine) auch wenn immer nur eins benutzt wird.

von Nop (Gast)


Lesenswert?

RAMbuff schrieb:
> Meine Frage
> ist, ob der Compiler irgendwie erkennt oder ich ihm sagen kann, dass er
> ruhigen Gewissens beide Variablen an einer Adresse ablegen soll da eh
> immer nur eine in Verwendung ist.

Klar kannste beide an eine Adresse legen:
1
char uart0RxBuf[127];
2
char uart0TxBuf[127];
3
#define uart1RxBuf uart0RxBuf
4
#define uart1TxBuf uart0TxBuf

Und schon liegen jeweils beide RX-Buffer und beide TX-Buffer an einer 
Adresse.

von RAMbuff (Gast)


Lesenswert?

Mike hat recht. Entweder ich besitze einfach nur einen großen Maßkrug, 
den ich für alles nehme. Ganz verrückte würden ihn vlt. sogar als 
Nachttopf verwenden. Funktionieren würde es sicher.

Aufräumen meint free, bzw. realloc?

von fop (Gast)


Lesenswert?

Wenn der ganze Code zum Bearbeiten der Daten in jeweils eine Funktion 
passt, geht auch eine lokale Varibale dieser Funktion. Wird die Funktion 
verlassen, ist die Variable Geschichte.
Ansonsten kannst Du auch auf den Optimizer des Compilers hoffen. Manche 
schaffen es, den Überblick zu behalten, wann welcher Wert nicht mehr 
gebraucht wird, bzw. welche Variablen nie gleichzeitig gebraucht werden 
und legen das übereinander. Spätestens wenn Du das ganze auf mehrere 
Dateien aufteilst ist aber Schluß mit dem automatischen Erkennen.

Wenn Du mit einer Variablen oder mit einer Union (2 Namen für den selben 
Speicherplatz : noch schlimmer, weil undurchsichtiger) arbeitest, bist 
Du selbst dafür verantwortlich nichst zu überschreiben, was Du nochmal 
brauchst.

Ansonsten gibt es da auch noch <jehova>malloc()</jehova>, aber dafür 
wird man ja hier gesteinigt und die Diskussion verlässt sofort und 
unwiederbringlich die technische Ebene.

von Nop (Gast)


Lesenswert?

fop schrieb:
> Ansonsten gibt es da auch noch <jehova>malloc()</jehova>, aber dafür
> wird man ja hier gesteinigt und die Diskussion verlässt sofort und
> unwiederbringlich die technische Ebene.

Recht so, denn wieso malloc, wenn es auch ein define tut. ^^

von Stefan K. (stefan64)


Lesenswert?

>> Ansonsten gibt es da auch noch <jehova>malloc()</jehova>, aber dafür
>> wird man ja hier gesteinigt und die Diskussion verlässt sofort und
>> unwiederbringlich die technische Ebene.
>
> Recht so, denn wieso malloc, wenn es auch ein define tut. ^^

Weil beides ungefähr so unterschiedlich ist wie ein Auto malen oder ein 
Auto kaufen?

Aber Spaß beiseite: ich finde das Beispiel mit einem Glas etwas 
unglücklich. Ein UART-Buffer wird in der Regel benutzt, damit die 
Funktionen, die ihn befüllen, nicht bis zum bitteren letzten versendeten 
Byte warten müssen. Um im Bild zu bleiben: wenn Du mittags auf einen 
anderen Buffer umschaltest, die Daten vom Frühstück aber erst halb 
versendet sind, dann hast Du eben Datenverlust.

Viele Grüße, Stefan

von fop (Gast)


Lesenswert?

Weil #define und Union verbergen, dass es nur einen Speicherbereich 
gibt. Selbst mit dem gleichen Namen, macht man an so Stellen Fehler, die 
man nur schwer findet.

Also die Komfortlösung ist : eine Tasse für den Kaffee zum Frühstück und 
eine Tasse für die Hühnerbrühe zum Mittag.
Nimmst Du nur eine Tasse, musst Du den Rest Kaffee wegkippen, bevor Du 
die Hühnerbrühe reinmachst. Solltest Du nach dem Mittag Lust auf den 
Rest Kaffee haben, geht was schief, denn statt des erwarteten Kaffees 
trinkst Du den Rest Hühnerbrühe.
Das eigentliche Problem wird nicht durch eine Tasse gelöst, die auf der 
einen Seite gelb und auf der anderen Seite grün ist. Die Du dann drehst, 
je nachdem, ob Du jetzt gerne Kaffee oder Hühnerbrühe möchtest. Das 
ändert nichts am Inhalt und an der Tatsache, dass es eine Tasse ist.
Du könntest Dir natürlich Tassen beim Nachbarn borgen und immer wieder 
zurück bringen, wenn sie leer sind. Da gibt es natürlich Leute, die zu 
recht sagen : Was ein Aufwand. Wobei der natürlich auch vom Nachbarn 
abhängt. Wie gut der seinen Geschirrschrank aufgeräumt hat und wie fix 
er ist. Wie lange es also dauert, bis er Dir eine Tasse rausgekramt hat 
bzw. sie wieder zurück genommen.

Jetzt darfst Du meine Geschichte den beschriebenen Lösungen zuordnen.

von Steffen R. (steffen_rose)


Lesenswert?

Nop schrieb:
> Recht so, denn wieso malloc, wenn es auch ein define tut. ^^

Ein malloc() würde dir nicht den Speicher geben, der noch in Benutzung 
ist (noch kein free() nach dem Frühstück). per Define würdest Du in den 
Speicher mit Kaffee die Hünerbrühe drüberkippen, sollte dieser noch in 
Benutzung sein.

von A. S. (Gast)


Lesenswert?

Ein Sendepuffer macht keinen Sinn, wenn es 2 unabhängige Uarts sind.

Nimm zwei, wenn sie im Hintergrund senden,
oder keinen, wenn sie blockierend senden.

von C++ (Gast)


Lesenswert?

RAMbuff schrieb:
> Versteht ihr was ich meine!?

Constructor/destructor vielleicht?

von Nop (Gast)


Lesenswert?

Steffen R. schrieb:
> per Define würdest Du in den
> Speicher mit Kaffee die Hünerbrühe drüberkippen, sollte dieser noch in
> Benutzung sein.

Das stimmt, aber das war nunmal die Frage des OP - wie man beide 
Variablen an dieselbe Adresse bekommt und kein separater Speicher 
benutzt wird.

von Steffen R. (steffen_rose)


Lesenswert?

Nop schrieb:
> Das stimmt, aber das war nunmal die Frage des OP

Deine erste Antwort dazu fand ich gut. Ich bezog mich nur auf deine 
zweite Erwiderung auf einen Alternativvorschlag.

Nop schrieb:
> Recht so, denn wieso malloc, wenn es auch ein define tut. ^^

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.