mikrocontroller.net

Forum: PC-Programmierung Warum wird beim Inkrementieren eines Doppelpointers immer um 8 Speicheradressen inkrementiert?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: Miau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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?

Autor: A. K. (prx)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Weil ein Byte 8 Bits hat und ein 64-Bit Pointer 8 Bytes.

Autor: nocheinGast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil ein Pointer 8 Bytes groß ist.

Autor: versus (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
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.

Autor: Miau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: foobar (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
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.

Autor: Miau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: foobar (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Und einige wollen ein Pony ...

Autor: DPA (Gast)
Datum:

Bewertung
2 lesenswert
nicht lesenswert
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...

Autor: Volle (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Sebastian S. (amateur)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Spiel doch mal mit dem sizeof-Operator.
Die meisten Compiler wissen was sie tun.

Autor: Bernd K. (prof7bit)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: K. S. (the_yrr)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
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.

Autor: K. S. (the_yrr)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Miau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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
Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Miau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Εrnst B. (ernst)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
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
./meinProgram 'Hallo Welt'

-->
 2e 2f 6d 65 69 6e 50 72 6f 67 72 61 6d 00 48 6c 6c 6f 20 57 65 6c 74 00

Autor: Jonas B. (jibi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>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

Autor: Miau (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Miau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Gaast255 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.