Moin Leute, ich habe folgendes Programm: int main(int argc, char **argv) { printf("%p\n",argv); argv++; printf("%p",argv); return 0; } mein Ausgabe ist: 0x7fffe4e24568 0x7fffe4e24570 Warum wird es immer um 8 Byte inkrementiert?
Weil ein Byte 8 Bits hat und ein 64-Bit Pointer 8 Bytes.
Weil ein Pointer 8 Bytes groß ist.
argv ist ein Pointer auf ein Array von Pointern. Da Pointer in einem 64-Bit System aus 8 Bytes bestehen, wird argv beim Inkrementieren um 8 erhöht.
Ah das klingt logisch. Beim 16 bit wert (z.b. word) würde er also immmer 2 Byte weiterspringen. Vielen Dank! Ich hätte aber noch 2 Fragen. Wenn ich z.B. char arrays definiere z.b. char test[4] hat er immer am Ende der Adresse ein 0. also z.B. 0x7fffe4e24570. Egal wieviele hintereinander arrays ich definiere. Ist das so ein C-Ding das die immer bei 0 Anfangen? Und bei meinem argv war immer am Ende eine 8 an dem ersten Rechner. An einem anderen immer eine 0. Gibts dazu eine Erklärung? Gruß Miau
Der Fachbegriff dafür ist "Alignment". Einige Datentypen müssen an bestimmten vielfachen Bytes liegen (Prozessoranforderung), z.B. Pointer an vielfachen der Pointergröße, also bei 32-Bit-Pointer an 4-Byte-Grenzen - die anden dann immer auf 0, 4, 8 oder C. Byte-Arrays können an sich an beliebigen Grenzen liegen, aber einige Prozessoren können schneller darauf zugreifen, wenn sie auch an bestimmten Grenzen liegen. Der C-Compiler weiß das und legt sie dann auch passend.
Ah ok Danke! Also zu meinem anliegen, ich wollte immer eine Speicheraddresse mit 0 am Ende. Daher kann ich doch immer solange inkrementieren bis am Ende eine 0 rauskommt oder? Weil die 0 ist immer dabei.
Und einige wollen ein Pony ...
Miau schrieb: > Also zu meinem anliegen, ich wollte immer eine Speicheraddresse mit 0 am > Ende. > Daher kann ich doch immer solange inkrementieren bis am Ende eine 0 > rauskommt oder? Weil die 0 ist immer dabei. Ich glaube das ist entweder eine schlechte Idee oder deutet auf ein grösseres Problem hin, meine Glaskugel hört nicht mehr auf zu schreien...
Miau schrieb: > Also zu meinem anliegen, ich wollte immer eine Speicheraddresse mit 0 am > Ende. Dann verwende die Oktale Schreibweise dann ist dein Wunsch für dein 64 Bit System ganz einfach zu erfüllen
Spiel doch mal mit dem sizeof-Operator. Die meisten Compiler wissen was sie tun.
DPA schrieb: > meine Glaskugel hört nicht mehr auf zu > schreien... Sehr schön formuliert! Ich beobachte nämlich ein ähnliches Phänomen bei meiner Glaskugel und wußte bisher nur nicht wie man das am besten mit Worten beschreiben kann. Schreien trifft es ganz gut.
Miau schrieb: > Also zu meinem anliegen, ich wollte immer eine Speicheraddresse mit 0 am > Ende. > Daher kann ich doch immer solange inkrementieren bis am Ende eine 0 > rauskommt oder? Weil die 0 ist immer dabei. kannst du sicher, nur was dan da drin steht ist eher zufällig. Irgendwann bekommst du halt nen segfault zurück. Stell dir vor du stehts vor nem Aktenschrank und suchst die ersten Ordner von oben links (weil da was wichtiges drin ist). bis dir dann auffällt dass du heute keine Lust darauf hast und nur die gelben auf der rechten Seite lesen willst. kann man so machen, wird aber scheiße.
Miau schrieb: > Wenn ich z.B. char arrays definiere z.b. char test[4] hat er immer am > Ende der Adresse ein 0. also z.B. 0x7fffe4e24570. Egal wieviele > hintereinander arrays ich definiere. > Ist das so ein C-Ding das die immer bei 0 Anfangen? das hat damit zu tun wie der Speicher organisiert ist, Variablen können nicht beliebig beginnen. Wenn der Ram mit 32bit Wörtern arbeitet beginnt halt eine Variable immer am Anfang davon. Wenn variablen wild über die Grenzen gehen würden, würde ein Lesebefehl zu zwei Lesebefehlen, zwei shifts und einem OR werden. Miau schrieb: > bei meinem argv war immer am Ende eine 8 an dem ersten Rechner. An einem > anderen immer eine 0. Gibts dazu eine Erklärung? hängt von Hardware, Compiler, Betriebssystem usw ab.
Programmierer auf x86- bzw. x84-Systemen sind auch sehr verwöhnt, d.h. dort spielt das Alignment keine allzu große Rolle, ganz im Gegensatz z.B. zu ARM-basierten Prozessoren. Bei x86 sind beliebig krumme Zugriffe zulässig, aber sie werden ggf. mit einigen Strafzyklen auf Grund mehrfacher Buszugriffe belohnt. Das fällt aber meistens nicht sofort auf.
Ist eine Schulaufgabe. Ich soll den Memdump ab der Adresse 0 anfangen auszugeben. War nur für mich zum Verständnis. Sry hätte ich schreiben sollen.
Andreas S. schrieb: > Bei x86 sind beliebig krumme Zugriffe > zulässig, aber sie werden ggf. mit einigen Strafzyklen auf Grund > mehrfacher Buszugriffe belohnt. Es kann erheblich teurer werden als man vermutet. Die Mechanik der Load/Store Operationen von OOO-Cores kommt u.U. nicht gut damit zurecht.
:
Bearbeitet durch User
Miau schrieb: > Ist eine Schulaufgabe. > Ich soll den Memdump ab der Adresse 0 anfangen auszugeben. > War nur für mich zum Verständnis. > Sry hätte ich schreiben sollen. Dann setz den Zeiger auf 0. Aber nicht wundern, wenn das Betriebssystem meckert.
Dirk B. schrieb: > Miau schrieb: >> Ist eine Schulaufgabe. >> Ich soll den Memdump ab der Adresse 0 anfangen auszugeben. >> War nur für mich zum Verständnis. >> Sry hätte ich schreiben sollen. > > Dann setz den Zeiger auf 0. > > Aber nicht wundern, wenn das Betriebssystem meckert. Die letzte stelle einer Adresse sollte 0 sein. Nicht komplett 0. Sondern wie z.B. 0x7fffe4e24570
Miau schrieb: > Die letzte stelle einer Adresse sollte 0 sein. Bei welcher Zahlenbasis? Nur weil dein Compiler bei %p Basis 16 nimmt, muss das nicht für andere gelten.
Miau schrieb: > Ist eine Schulaufgabe. > Ich soll den Memdump ab der Adresse 0 anfangen auszugeben. > War nur für mich zum Verständnis. > Sry hätte ich schreiben sollen. Gib mal die volle Aufgabenstellung. Wenn Hexdump, dann solltest du vielleicht erstmal einen "uint8_t *" verwenden, damit du byteweise über die Eingabe laufen kannst. Und bist du dir mit "letzte Stelle 0" sicher? War nicht eher ab "argv[0][0]" oder so gefragt? also
1 | ./meinProgram 'Hallo Welt' |
2 | |
3 | --> |
4 | 2e 2f 6d 65 69 6e 50 72 6f 67 72 61 6d 00 48 6c 6c 6f 20 57 65 6c 74 00 |
>Programmierer auf x86- bzw. x84-Systemen sind auch sehr verwöhnt, d.h. >dort spielt das Alignment keine allzu große Rolle... Stimmt, hält man das 48 Byte Alignment auf dem Stack nicht ein passiert meistens nichts, aber wehe eine MMX-Instruktion wird aufgerufen... Ansonsten wird der Stack tatsächlich sogar um 16 Bytes vergrößert um 8 Bytes zu gewinnen, eben wegen dem Alignment... Gruß Jonas
Also ich habe das hinbekommen und die Aufgabenstellung war nur wie im Bild zu sehen. Ich sollte ein paar Argumente übergeben (text, Anzahl zeilen, cin,cout). Dann das Speicherabbild vom Stack (ab einer Addresse 0) und dann zwischenspeichern in Heap und das ausgeben. Im Heap aber nur den Text. Restlichen Ausgaben die ich machen musste sind glaub ich selbst erklärend. Ich weiß bloss nicht ob es so gern gesehen ist in meiner Schule die Lösung hier zu posten da es oft dieselebe Aufgabe jedes Jahr ist.
Ich bedanke mich trtzdm nochmal für eure Antworten. Ihr habt mir zum verstehen der Sinn der Aufgabe weitergeholfen. Allerdings finde ich es schwer sowelche absoluten Basics nur zu googlen sehr schwer.
Miau schrieb: > Ich bedanke mich trtzdm nochmal für eure Antworten. Ihr habt mir zum > verstehen der Sinn der Aufgabe weitergeholfen. Allerdings finde ich es > schwer sowelche absoluten Basics nur zu googlen sehr schwer. Deswegen gibt es Bücher
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.