Frage zur Speicherallokation

Hallo liebe Gemeinde,

zur Zeit arbeite ich mich gerade in das Thema "Speicherallokation" und Pointer ein. Da ich noch Anfänger bin, ist mir ein "Problem" aufgefallen, das ich mir nicht erklären kann, vielleicht könnt ihr es. Hier mal mein Code, der zuerst ein 'b'(=98) in die allokierten Adressen schreibt und anschließend das Alphabet drüberschreibt. Des weiteren gibt er auch die allokierten Speicheradressen zur Kontrolle für mich selbst aus. Der Code hat natürlich keinen ernsthaften Sinn... :slight_smile:

void setup() {
 // put your setup code here, to run once:
Serial.begin(9600);
char *ausgabe;
char memo=(char*)malloc(27*sizeof(char)); //gibt erste Adresse zurück
Serial.println((unsigned int)memo);
ausgabe=memo; //Pointer zeigt auf Adressse

for (int i=0;i<27;i++){
*ausgabe=98;
Serial.println(*ausgabe);
Serial.println(i);
Serial.println("-----");
Serial.println((unsigned int)ausgabe);
ausgabe++;
}


Serial.println("Adresse zurücksetzen");
ausgabe=memo;
Serial.println((unsigned int)ausgabe);

for (int i=65;i<91;i++){

 Serial.println("Hallo");
 *ausgabe=i;
 Serial.println((unsigned int)ausgabe);
 Serial.println(*ausgabe);
 ausgabe++;
 Serial.println((unsigned int)ausgabe);
 Serial.println(*ausgabe);

}
Serial.println((unsigned int)ausgabe);

//Abschließende NULL
*ausgabe='';
ausgabe=memo;
Serial.println(ausgabe);

 }



void loop() {
 // put your main code here, to run repeatedly:

}

Jetzt zum Problem: Mir fällt aus, dass (bei mir) die Adressreservierung bei "65514
" beginnt und bis 65535 läuft, dann wieder bei 0 anfängt und weiterläuft. Dadurch endet das ausgegebene
Alphabet quasi bei "V". (???)

Zur Lösung, die ich mir nicht erklären kann. Normalerweise sollte ja ein Pointer immer auf den Datentyp zeigen, von dem er selbst ist. Ersetze ich den Ausdruck

char memo=(char*)malloc(27*sizeof(char)); //gibt erste Adresse zurück

durch

int memo=(int*)malloc(27*sizeof(int)); //gibt erste Adresse zurück

funktioniert es. Dennoch würde ich gerne wissen warum, kann es einer erklären? Ich vermute es hängt mit dem überlaufen zusammen. Man sieht bei der "Lösung" auch, dass (bei mir) die Adresse des ersten Elementes bei 490 beginnt. Warum varriert der allokierte Adressbereich so stark in beiden Fällen? Kann es Probleme mit sich bringen, wenn ein char auf einen int zeigt? Wie sollte man besser vorgehen?

Beste grüße, danke für eure Hilfe und mit der bitte um Nachsicht für etwaige Fehler, es ist mein erster Beitrag... :slight_smile:

Beste Grüße

Wenn ich Dein Programm für den UNO übersetzen lasse, ist der Kompiler sehr unzufrieden. Wie Du zu irgendwelchen Ergebnissen kommst, ist mir daher nicht klar.

Welche Hardware verwendest Du?

C ist schlampig, da kann ein Pointer auf irgendwas zeigen, und *pointer liefert dann etwas das dem Typ des Pointers entspricht. Ob der Pointer oder Ausdruck auf eine gültige Adresse zeigt, oder auf Daten die anderweitig benutzt werden, das ist dem Compiler egal.

Bei malloc() werden ausreichend viele Bytes für den angegebenen Datentyp angelegt, bei char also 1 Byte pro Element und bei int 2 Bytes pro Element. Ob man diesen Speicher an ein char* oder int* zuweist ist dem Compiler egal weil malloc() ein void* liefert, also Adresse von irgendwas. Mit einem Typecast kann man daraus machen was man will, das wird nicht geprüft. Wenn der Compiler ganz alt oder schlampig ist, dann meint er auch "ein Pointer ist ein int, ein int ist ein Pointer" und läßt sogar zu, daß man eine Adresse an eine int Variable zuweist, und ein *intvar liefert dann meist ein char.

Mit char memo = malloc(...); ist und bleibt memo ein Byte, kann also nur Werte von 0 bis 255 speichern. Was *memo liefert, wenn der Compiler keinen Fehler meldet, ist mir schleierhaft.

DrDiettrich:
Bei malloc() werden ausreichend viele Bytes für den angegebenen Datentyp angelegt, bei char also 1 Byte pro Element und bei int 2 Bytes pro Element.

Das ist falsch!

malloc(size) reserviert einen Speicherbereich von size Bytes, wenn es kann. Deshalb sollte man auch immer den Rückgabewert prüfen. Wenn der ein null-Pointer ist, konnte der Speicherbereich nicht angelegt werden.

Gruß Tommy

Leitsatz:
Wer Pointer kennt, nimmt lieber Referenzen.

char memo=(char*)malloc(27*sizeof(char));
char * memo=(char*)malloc(27*sizeof(char));

Tommy56:
Das ist falsch!

malloc(size) reserviert einen Speicherbereich von size Bytes, wenn es kann.

Stimmt, die tatsächliche Bytezahl muß man selbst berechnen. Ich war da gedanklich wohl schon beim Array-Zugriff...

agmue:
Wenn ich Dein Programm für den UNO übersetzen lasse, ist der Kompiler sehr unzufrieden. Wie Du zu irgendwelchen Ergebnissen kommst, ist mir daher nicht klar.

Welche Hardware verwendest Du?

Hallo agmue,
ich verwende einen Uno-Klon zum herumdoktern.
LG

combie:
Leitsatz:
Wer Pointer kennt, nimmt lieber Referenzen.

char memo=(char*)malloc(27*sizeof(char));
char * memo=(char*)malloc(27*sizeof(char));

Besten Dank, es funktioniert :o !!! Nach weiteren Feststellungen muss anscheinend das Ergebnis von malloc() immer einem zuvor deklarierten Pointer zugewiesen werden . Das Zwischenspeichern des Ergebnisses vom malloc-Aufruf in einer normalen Variable , wie ich es getan habe, und anschließende zuweisen an einen Pointer, macht anscheinend nachträglich Probleme. Warum auch immer.

Warum auch immer.

Beim Zuweisen des Pointers an eine 8Bit Variable, werden 8 Bit von dem 16 Bit Pointer abgeschnitten.
Der ehemals gültige Pointer ist danach verstümmelt.

Das ist der Grund:
Absichtliche Verstümmelung.
Und sich dann wundern, dass es nicht funktioniert?

Das Zwischenspeichern des Ergebnisses vom malloc-Aufruf in einer normalen Variable , wie ich es getan habe,

Das kann man natürlich tun.
Es gibt KEINEN Grund dafür, es zu tun.
Aber man kann es .
Es ist voll daneben.
Aber es funktioniert, wenn man dabei nichts Verstümmelt.

Normalerweise sollte ja ein Pointer immer auf den Datentyp zeigen, von dem er selbst ist

Das sieht erstmal falsch aus.
Ein char* ist jedenfalls etwas völlig anderes als ein char.
Dass hier ein int groß genug ist, um den Wert eines Zeigers zu speichern, sorgt hier dafür, dass du zufrieden bist. Falsch ist es trotzdem.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.