Forum: Compiler & IDEs Pointer Verständnis Problem


von ernst (Gast)


Lesenswert?

Hallo,

ich habe da Verständnis Probleme mit C Grundlagen (hoffentlich gehört 
das hier überhaupt hin).

nachdem ich einen Pointer deklariere, z.B.
1
char *ptr;

dann die Adresse der Variable a übergebe
1
char a = 55;
2
ptr = &a;

und jetzt über den Pointer den Inhalt von a an die Variable b kopieren
1
char b;
2
b = *ptr;

Dann sollte ja jetzt b=55 sein.

So weit, so gut.
ptr "trägt" also die Speicheradresse von der Variable a.

Jetzt habe ich in einem Programm gesehen, dass so etwas gemacht wurde:
1
char *ptr="0123456";

Die Pointeradresse wurde quasi als String Variable genutzt.

zur Ausgabe wurde dann eine Variable i als String gewandelt und in den 
Pointer geschrieben.
1
unsignet char i = 555;
2
itoa(i,ptr,10);
3
...

Kann mir jemand den Zusammenhang erklären? Mit den oben genannte 
Erklärungen zu den Grundlagen ist mir die eben erwähnte Vorgehensweise 
nicht klar.


Danke
ernst

von Patrick (Gast)


Lesenswert?

Hallo Ernst,

der Compiler legt den String automatisch in der Stringtabelle des 
fertigen Programms ab. Dieser String bekommt dann irgendeinen mehr oder 
weniger kryptischen Namen. In ptr wird tatsächlich nur die Adresse 
dieses automatisch
angelegten Strings abgelegt.
Jeden Formatstring der in einem printf o.ä. Aufruf verwendet wird, legt 
der Compiler so automatisch an.

Gruß
Patrick

von yalu (Gast)


Lesenswert?

Wie Patrick schon geschrieben hat, legt die Zeile
1
char *ptr = "0123456";

eine Stringkonstante im Speicher an und zusätzlich die Zeigervariable
ptr, die so initalisiert wird, dass sie auf den Anfang der
Stringkonstante zeigt.
1
itoa(i, ptr, 10);

Das ist ein Fehler. Da es sich bei dem String, worauf ptr zeigt, um
eine Konstante handelt, darf er nicht beschrieben werden. Je nach dem,
wie auf dem Zielsystem der Speicher verwaltet wird, kann diese Anweisung
funktionieren, einen Speicherzugriffsfehler auslösen oder auch gar
nichts tun. Besser:
1
char array[] = "0123456";

Im Gegensatz zu oben wird nun ein beschreibbares char-Array angelegt,
das groß genug ist, um den String "0123456" aufzunehmen. Die
Array-Elemente können nun nach Belieben verändert werden. Eine
zusätzliche Zeigervariable wird nicht angelegt, was etwas Speicher
spart. array kann aber ähnlich wie ein char-Zeiger verwendet werden,
also:
1
itoa(i, array, 10);

Ganz schön ist diese Lösung aber immer noch nicht. Schreibst du mit
itoa eine Zahl in das Array, die mehr als 7 Stellen hat, wird das
Array überlaufen. Besser ist es, das Array explizit zu dimensionieren,
und zwar so groß, dass die größte auftretende Zahl einschließlich einem
eventuellen Vorzeichen und der String-Ende-Null darin Platz hat, also
bspw. so:
1
char array[11] = "0123456";

Und noch etwas: itoa ist keine Funktion der C-Standardbibliothek und
sollte deswegen vermieden werden. Statt dessen sollte sprintf oder
noch besser snprintf verwendet werden, um numerische Werte in ihre
Zeichendarstellung umzurechnen:
1
sprintf(array, "%d", i);

bzw.
1
snprintf(array, sizeof array, "%d", i);

Der Unterschied zwischen sprintf und snprintf liegt darin, dass
letztere Array-Überläufe vermeidet, indem sie die Größe des übergebenen
Arrays berücksichtigt.

von ernst (Gast)


Lesenswert?

@ yalu:

Vielen Dank für deine ausführliche Antwort!

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.