ENGLISH VERSION |
|
Links | | | Forum | | | Kommentare | | | News melden |
Chat | | | Umfragen | | | Newsticker | | | Archiv |
amiga-news.de Forum > Programmierung > Pointer-Wunder | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
-1- | [ - Beitrag schreiben - ] |
09.12.2002, 15:00 Uhr Inferno Posts: 157 Nutzer |
Hallo Programmier-Freunde! habe mehrere Tage damit zugebracht, einen Fehler zu finden, der regelmäßig zum Absturz führte und hier ist der Wicht: (Storm C 4 unter verschiedenen configs, u.a. WinUAE und "echte" Amigas) --- snip --- char buffer[4096]; int index=4; fillString(index, &buffer[0]); printf("String is: %sn", &buffer[0]); --- /snip --- Wenn ich dieses Fragment wie folgt ändere, läufts einwandfrei: --- snip2 --- char *buffer = new char[4096]; int index=4; fillString(index, buffer); printf("String is: %sn", buffer); delete[] buffer; --- /snip2 --- Könnte es sein, daß er beim & - Operator "relative" Pointer benutzt (da buffer ja auf dem Stack angelegt wird, könnt's relativ zum TopOfStack sein (o.ä.)) ????? Bin zwar glücklich den Fehler gefunden zu haben, würde aber trotzdem ganz gerne wissen, WARUM die erste Version nicht funktioniert hat !! Gruß, Inferno [ - Antworten - Zitieren - Direktlink - ] |
09.12.2002, 15:19 Uhr Holger Posts: 8116 Nutzer |
Sag lieber, was Deine fillString-Funktion eigentlich macht. Wenn Du über die Array-Grenze hinweg schreibst, überschreibt die erste Variante Deinen Stack (sehr hohe Absturzwahrscheinlichkeit), bei der zweiten Variante fremden Speicher (mittlere Absturzwahrscheinlichkeit). mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
09.12.2002, 15:23 Uhr Inferno Posts: 157 Nutzer |
Hallo Holger, die fillString-Routine füllt den buffer mit einem String aus einem Array von Strings (quasi). genaugenommen ist es ein Array von Objekten, die alle einen String* als property haben und fillString nutzt die strcpy - Funktion, um den Inhalt zu kopieren. Dabei bin ich mir aber 100% Sicher, daß keiner der Strings länger als 4096 Bytes ist, das max. ist so um die 50 Bytes ... Da hatte ich nämlich auch schon dran gedacht, und deshalb hatte ich den buffer entsprechend groß reserviert. * String = array of chars :-) Ciao, Inf! [ - Antworten - Zitieren - Direktlink - ] |
09.12.2002, 18:44 Uhr thomash Posts: 172 Nutzer |
Hi. Über das Problem bin ich auch schon mal gestolpert, war aber schon beim Maxon C-Compiler. Versuchs mal mit &(buffer[0]) statt &buffer[0] dann sollte es gehen. Es scheint, daß hier Array- und Pointer-Prioritäten kollidieren. Beim alten Aztec C kein Problem, aber je korrekter die Implementation, umso genauer muß der Programmierer schreiben, was er will. Sowieso gilt doch immer: Lieber zu viel klammern, als zu wenig. Ciao, Hoin. [ - Antworten - Zitieren - Direktlink - ] |
09.12.2002, 19:56 Uhr Holger Posts: 8116 Nutzer |
Normalerweise sollte auch einfach nur buffer reichen. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
10.12.2002, 10:00 Uhr gni Posts: 1106 Nutzer |
Zitat:Wo bitte ist der Unterschied? Zitat:So ein Quatsch! Entweder es ist richtig oder es ist falsch. [ - Antworten - Zitieren - Direktlink - ] |
10.12.2002, 10:18 Uhr thomas Posts: 7718 Nutzer |
Zitat: Bei dem zweiten kommt es darauf an, welche Prioritäten der Compiler setzt. Es könnte auch als (&buffer)[0] interpretiert werden, was etwas völlig anderes ist. Zitat:Zitat:So ein Quatsch! Entweder es ist richtig oder es ist falsch. Kein Quatsch. Je nach Compiler werden Ausdrücke unterschiedlich interpretiert. Welcher Compiler dabei fehlerhaft ist, sei mal dahingestellt. Zuviele Klammern machen in jedem Fall Sinn. Gruß Thomas -- Email: thomas-rapp@web.de Home: home.t-online.de/home/thomas-rapp/ [ - Antworten - Zitieren - Direktlink - ] |
10.12.2002, 10:49 Uhr Inferno Posts: 157 Nutzer |
Hallo! @thomas: Danke für den Tipp, werde es mal ausprobieren ... (hatte bisher leider noch keine Zeit dazu) ... und dann hier posten, ob es geholfen hat! Ciao, Inf! [ - Antworten - Zitieren - Direktlink - ] |
11.12.2002, 10:40 Uhr Holger Posts: 8116 Nutzer |
Zitat:Eigentlich ist ein array ja nur ein Pointer auf's erste Element. Dann wäre: Wenn da ein Unterschied besteht, werden Arrays völlig anders gehandhabt, ich würde es fehlerhaft nennen. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
11.12.2002, 13:02 Uhr thomas Posts: 7718 Nutzer |
Das ist wahr, wenn der Zeiger als Pointer definiert ist, also char *pointer. Bei einer Array-Definition (char array[]) bekommst du bei &array die Adresse des ersten Elements. Also &array == array == &array[0]. Wenn du es nicht glaubst, probier es aus. Gruß Thomas -- Email: thomas-rapp@web.de Home: home.t-online.de/home/thomas-rapp/ [ - Antworten - Zitieren - Direktlink - ] |
11.12.2002, 19:12 Uhr thomash Posts: 172 Nutzer |
Hallo Leute, bin wieder da. Gestern hatte ich Geburtstag und den Rechner nicht angeschalten, deswegen konnte ich mich nicht wehren. Der ganze Storm-C V4 macht mir leider keinen sehr guten Eindruck. Ich habe immer irgendwelche nicht nachvollziehbaren Fehlermeldungen, unter anderem auch mit der Pointer/Array-Geschichte. Manchmal habe ich Compilerfehler, da muß ich nur eine Zeile löschen und neu eintippen (nein, es war kein Tippfehler drin) und es geht wieder zu übersetzen. Ich vermute, daß der GCC (auch in der Storm-Variante) jeweils andere Übersetzungsmethoden anwendet, je nachdem, ob man für einen String char * oder char[] bei der Deklarierung als Datentyp benutzt. Noch leckerer kommt das ganze bei char *-Arrays wo ich zum ersten Mal über diese Eigenheit gestolpert bin (lokalisierte Strings als Array...). Eigentlich sollte man einen String ja auch nicht verändern, deswegen ist &string[index] schlechter Stil, aber ich benutze es auch gerne, um z.B. einen Shortcut zu überspringen. char *kopier = "cCopy"; puts(&kopier[1]); Dieses Fragment gibt dann nur "Copy" aus, man kann aber mit char c; c = kopier[0]; einen einzelnen Buchstaben auslesen (hier "c") und z.B. als Menüshortcut verwenden. Aber wehe, es kommt eines Tages Unicode ! Ich wollte mal vbcc ausprobieren, aber da meine Amigas zur Zeit defekt sind, dauert das noch. Naja, frohe Weihnachten noch, falls man sich nicht mehr trifft. [ - Antworten - Zitieren - Direktlink - ] |
12.12.2002, 14:10 Uhr Holger Posts: 8116 Nutzer |
Zitat:Damit veränderst Du den String nicht, aber übersichtlicher sieht es doch so aus: char *kopier = "cCopy"; puts(kopier+1); Oder? Zitat:Das funktioniert exakt genauso, wenn char 2 oder gar 4 bytes lang ist. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
12.12.2002, 14:41 Uhr Holger Posts: 8116 Nutzer |
Zitat: Nein. Wenn Du ein array benutzt, liefert &array die Adresse des Arrays. Diese Adresse hat dieselbe Position im Speicher wie das erste Element, da C-Arrays ja keine weiteren Daten enthalten als die Elemente. Aber genau deshalb ist ja die Typisierung der Pointer so wichtig. Denn wenn Du den Pointer auf ein Array dereferenzierst, ala (&array)[0] bekommst Du wieder das Array, also den Pointer auf das erste Element, welcher immer noch auf die gleiche Speicherstelle verweist, aber einen anderen Typ hat. Du kannst es doch mit einem einfachen Testprogramm sehen code:Der Adresse eines Arrays ist etwas anderes als die Adresse eines Pointers, deshalb verhalten sich &s1 und &s2 auch anders.#include <stdio.h> int main(int n, char**a) { char *s1="Hallo"; char s2[]={ 'W', 'e', 'l', 't', 0 }; printf("%s ", s1); printf("%s.n", s2); printf("s1=%08lx, ", s1); printf("&s1=%08lx, ", &s1); printf("&(s1[0])=%08lx, ", &(s1[0])); printf("(&s1)[0]=%08lx.n", (&s1)[0]); printf("s2=%08lx, ", s2); printf("&s2=%08lx, ", &s2); printf("&(s2[0])=%08lx, ", &(s2[0])); printf("(&s2)[0]=%08lx.n", (&s2)[0]); } Aber für die Pointer auf die Elemente (alle vom Type char*) spielt das keine Rolle. Zumindest wenn der Compiler keine Fehler hat. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ - Antworten - Zitieren - Direktlink - ] |
12.12.2002, 19:00 Uhr thomash Posts: 172 Nutzer |
Hallo Holger.Zitat: Ja, natürlich. Aber es widerstrebt mir noch mehr, einen String wie eine Zahl zu behandeln (Addition), auch wenn ein Pointer eigentlich nichts anderes ist. Aber ein Codefragment "kopier + 1" suggeriert unterschwellig und bei oberflächlichem Lesen einen Zahlentyp. Deswegen sollte man eigentlich beide Varianten nicht benutzen. Nur bei meiner kann ich noch erkennen, daß es ein String ist. Und stell Dir mal vor, irgendwann schreibst Du aus Versehen "kopier++", weils doch auf den ersten Blick dasselbe ist. Nur daß es dabei den Zeiger verbiegt... Ciao, Hoin. [ - Antworten - Zitieren - Direktlink - ] |
13.12.2002, 09:26 Uhr gni Posts: 1106 Nutzer |
Zitat:Nein, aber das ist eine Geschmacksfrage. Zitat:Wenn Du das nicht willst, hilft Dir const. [ - Antworten - Zitieren - Direktlink - ] |
13.12.2002, 18:53 Uhr Holger Posts: 8116 Nutzer |
Zitat:Tja, und mir widerstrebt es, gerade wenn man in C programmiert (ich vermeide das), eine Operation intuitiver aussehen zu lassen, als es im Endeffekt ist. &a[c] ist in C nichts anderes als a+c und C stellt keinerlei array-Funktionalität zur Verfügung. Bei der Additionsschreibweise fällt es viel mehr auf, das c keinerlei Beschränkungen unterworfen ist und man selber aufpassen muß. Zitat:Es ist kein String. Zitat:Du meinst a++b statt a+b? Haut wohl nicht ganz hin... Das der ++ Operator eine gewisse Unübersichtlichkeit besitzt, hat nichts mit Pointer oder nicht Pointer zu tun. Das gilt für Integer-Werte genauso. mfg -- Good coders do not comment. What was hard to write should be hard to read too. [ Dieser Beitrag wurde von Holger am 13.12.2002 editiert. ] [ - Antworten - Zitieren - Direktlink - ] |
-1- | [ - Beitrag schreiben - ] |
amiga-news.de Forum > Programmierung > Pointer-Wunder | [ - Suche - Neue Beiträge - Registrieren - Login - ] |
Impressum |
Datenschutzerklärung |
Netiquette |
Werbung |
Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten. |