001
11.04.2006, 09:42 Uhr
0xdeadbeef
Gott (Operator)
|
Au weia, da mischste aber einiges durcheinander...
Also, zunächst mal ist
kein char-array, sondern ein Array von Zeigern auf char. Und diese Zeiger sind im Moment alle uninitialisiert, zeigen also ins Nirvana. Ferner
C++: |
char* lexem = "Alf";
|
ist das hier so nicht ganz korrekt. "Alf" ist eine String-Konstante, wenn du da reinschreibst, gibt das nachher böse Probleme. Viele Compiler fressen das so, die meisten werden aber deswegen warnen. In jedem Fall ist
C++: |
char const *lexem = "Alf";
|
richtiger (Zeiger auf konstanten char). Allerdings ist lexem bereits null-terminiert. Im übrigen, selbst wenn
keinen Compilerfehler verursacht, was es, denke ich, eigentlich sollte, dann wird es auf den Zeiger lexem Null draufaddieren, macht also garnichts. lexem ist ja keine Klasse wie std::string in C++, die Operatoren mit komplexen Funktionen überladen hat, sondern bloß eine Speicheradresse, also im Grunde nur eine Zahl.
Das hier:
C++: |
memcpy(list, lexem + NULL, 3 + 1); // kopiere "Alf" in "list" mit anschließendem NULL-Terminator
|
aus zwei Gründen Unfug, zum einen macht lexem + NULL nichts, zum anderen ist list kein char-Array. Du kopierst hier einen String in ein pointer-array, und die Pointer werden nachher irgendwo in ganz wilde Regionen zeigen.
Was die Ausgabe angeht, so wies aussieht, arbeitest du auf einer little endian 32-bit-architektur, dann ergibt das Sinn. Was passiert, ist folgendes: Ein Zeiger ist 32 bit, also 4 byte lang, ein char eins. Also sieht list nach der zweiten String-Zuweisung so aus:
Code: |
|Alf\0|\0\0\0\0|\0\0\0\0|ons\0|\0\0\0\0|...
|
wobei \0 ein NULL-Zeichen symbolisieren soll. wenn du list jetzt als string interpretierst, gibt er die Zeichen bis zum ersten NULL-ZEichen aus, also "Alf". wenn du die Pointer einzeln als Zeichen interpretierst, nimmt er den Zeiger als Zahl, schneidet ihn auf char-Größe zurecht und gibt das Ergebnis aus - auf einer little-endian-Architektur bedeutet das, er gibt das erste Byte des Zeigers aus, also 'A' bzw. 'o'. Wichtig dabei ist, dass list + 1 hier nicht etwa genau 1 auf die Speicheradresse von list addiert, sondern ein Element im Array vorangeht, also sizeof(*list) draufgibt. *(list + 1) ist das selbe wie list[1].
Die einfachste Möglichkeit, hier heran zu gehen, ist wohl
oder so, das sind dann 10 strings a 100 Zeichen. Komplizierter wirds mit
C++: |
char *list[10]; for(int i = 0; i < 10; ++i) list[i] = malloc(anzahl_benoetigter_zeichen);
// ...
for(int i = 0; i < 10; ++i) free(list[i]);
|
aber wenn du die Länge der Strings vorher nicht kennst, kannste da mit realloc und so halt flexibler reagieren. Ich hoffe, das hier hilft dir, viel Glück -- Einfachheit ist Voraussetzung für Zuverlässigkeit. -- Edsger Wybe Dijkstra |