char Pointer warum funktioniert es mit char und nicht mit char*



  • Hast du meine Erklärung verstanden?

    Wenn ja:
    dann sollte die Antwort auffindbar sein. ein bisschen kompliziert wird es natürlich sein, aber du wirst dich ein bisschen anstrengen müssen.

    Wenn nein:
    nachfragen. ich (und natürlich auch andere) erklären es gerne genauer



  • memcpy(&charPointer[0],chstr,(strlen(chstr))*(sizeof(char)));

    wenn ich die zeile hierzu so änder dann tut es 🙂

    stimmt so oder? das & von chstr weggelassen da dies ja schon ein pointer ist
    und danach berechne ich die größe also die anzahls charakter wo in dem string drin sind

    stimmt die erklährung so?

    danke nochmal



  • oli23 schrieb:

    stimmt die erklährung so?

    Ja.

    kleiner Stil tipp: sizeof(char) ist immer 1, du kannst es also weglassen.

    &p[0] und p sind beides die adresse des ersten elementes in p.

    folglich kann man diese zeile auf
    memcpy(charPointer, chstr, strlen(chstr));

    kürzen.
    da dies aber nur ein kopieren eines strings ist, kann man hier auch eine spezielle funktion zum kopieren von strings verwenden: strcpy

    strcpy(charPointer, chstr);



  • Sorry aber habs glaub doch no net so recht verstanden

    wenn ich die zeile
    memcpy(&charPointer[0],chstr,(sizeof(char*)));

    so schreib koiert er mir nur die ersten 4 zeichen von dem charakter String "char* chstr ="hallo";"

    weil sizeof(char*) eben 4 ist

    aber chstr ist doch ein Pointer und hat doch immer 4 Byte dann müßt es doch egal sein wie lang da mein charakter string"char* chstr ="hallo";" ist oder???



  • oli23 schrieb:

    Sorry aber habs glaub doch no net so recht verstanden

    Kein Problem.

    wenn ich die zeile
    memcpy(&charPointer[0],chstr,(sizeof(char*)));

    so schreib koiert er mir nur die ersten 4 zeichen von dem charakter String "char* chstr ="hallo";"

    weil sizeof(char*) eben 4 ist

    Ja.

    aber chstr ist doch ein Pointer und hat doch immer 4 Byte dann müßt es doch egal sein wie lang da mein charakter string"char* chstr ="hallo";" ist oder???

    chstr Zeigt auf den string "hallo"

    In C sind alle Strings nur ein "Array aus Buchstaben, das mit einem besonderen Zeichen (0) beendet wird".

    dh:

    char* chstr="hallo";

    irgendwo im speicher stehen die buchstaben:
    'h', 'a', 'l', 'l', 'o', 0

    chstr zeigt nun darauf.
    dazu muss man wissen: zeiger sind im prinzip ganz normale variablen. allerdings haben sie als wert nicht etwa 3 wie ein int oder 7.14 wie ein float sondern eine adresse im Speicher.

    kann man sich wie eine Straße vorstellen. Da stehen viele Häuser und alle haben Adressen. Wenn wir nun von dem Haus 7 reden, ist das eine Adresse. Ein Zeiger beinhaltet diese Adresse.

    Wenn wir nun aber wissen wollen was in dem Haus drinnen ist, müssen wir zu der Adresse Hause 7 gehen.

    In C macht man das so:
    char* adresse="haus 7";
    zugriff: zB adresse[0]

    nun ist adresse das 1. Zeichen dass bei der adresse "Haus 7" liegt.
    adresse[1] wäre das 2. zeichen.

    du kannst so ewig weiter 'schauen', deshalb gibt es diese 0 am ende. dh, wenn
    adresse[i] 0 ist, dann bist du am ende du darfst nicht weiter lesen.

    so, genug der abschweife.

    nun ist sizeof(char*) oder sizeof(adresse) idR 4, weil die adresse 4 bytes benötigt. Die Länge des Strings ist hierbei aber davon ja gänzlich unabhängig.

    vergleiche zB diese Adresse
    Gasse 3
    mit
    Großhinterdumpfing Allee 170-192 A

    die größe dr adresse sagt nichts über das Haus dass dort steht 😉

    mit strlen() bekommst du nun die länge des strings auf den gezeigt wird. strlen zählt nämlich die anzahl der zeichen bis eine 0 kommt.

    für das kopieren ist natürlich wichtig aus wievielen zeichen der string besteht und nicht wie groß die adresse ist.

    ich hoffe, jetzt ist alle klar 🙂
    wenn nicht, heute abend habe ich mehr zeit zum erklären.



  • bis dahin hab ich es verstanden.

    für das kopieren ist natürlich wichtig aus wievielen zeichen der string besteht und nicht wie groß die adresse ist.

    aber warum das?

    bei der memcopy codezeile unten in chstr steht ja die adresse von dem haus "hallo"
    und in der Adresse von Char Pointer steht ja noch nichts drin(leerer bauplatz) aber da ist platz weil ich ja speicher allokiert hab. So
    jetzt hat die adresse von chstr ja genau 4Byte (sizeof char*) und ich will doch einfach nur die Adresse con chstr wo auf das Haus hallo zeigt in charPointer Kopieren damit der auch auf hallo zeigt. Dabei sollt es doch egal sein wie lang "hallo"(also wieviel zeichen hallo hat)solang ich ich die ganze adresse also alle 4 Byte kopiere.

    Dem ist aber net so weil bei dem code unten eben nur die ersten 4 zeichen von dem string hallo kopiert werden.

    blick des net 😞

    char* charPointer;
    char* chstr ="hallo";

    memcpy(charPointer,chstr,(sizeof(char*)));



  • Jetzt ist die Adresse 0-4 schon belegt und ich kann meine char* Zeichenkette erst ab der nummer 5 speichern muss ich dann die Ausgabe mannuel (evt mit einer schleife wie das geht weiss ich machen) oder gibt es da ne einfachere möglichkeit mir die char* zeichenkette ab der nummer 5 auszugeben?

    und dann noch was echt merkwürdiges ich hol mit doch gar kein speicher oder halt 0 Speicher aber es geht alles wie immer warum das???macht des dann der compiler autoamtisch???
    wenn ich aber die zeile komplett weg lasse kommt dein Kompileriungsfehler aber beim ausführen "Segmentation fault" ist ja au klar also holt er doch net automatisch speicher aber mit 0 speicher holen geht es oder wie??? blick ich au net
    😞

    wäre echt klasse wenn du dich noch einmal um mich erbarmen könntest...

    char* charPointer;

    int main()
    {
    int len=10;
    char* chstr ="sodleeeeeeee";

    charPointer= new char[0]; //hole mit doch kein speicher warum geht des dennoch?????

    memcpy(&charPointer[5],chstr,(sizeof(char*)));

    cout <<charPointer[5]<<endl;
    cout <<charPointer[6]<<endl;



  • oli23 schrieb:

    für das kopieren ist natürlich wichtig aus wievielen zeichen der string besteht und nicht wie groß die adresse ist.

    aber warum das?

    Weil du ja Platz fuer deine Zeichenkette brauchst. Du musst ja vorher einen passend grossen Bauplatz haben (um mal beim Beispiel zu bleiben) sonst machst du beim Kopieren des Hauses ja u.U. die Nachbarhauser platt und das fuerst beim PC zu abstuerzen und Fehlern.

    quote="oli23"]So jetzt hat die adresse von chstr ja genau 4Byte (sizeof char*) und ich will doch einfach nur die Adresse con chstr wo auf das Haus hallo zeigt in charPointer Kopieren damit der auch auf hallo zeigt.[/quote]
    Hier kommst du zu einer entscheidenden Frage der Informatik. Soll es auf das GLEICHE oder das SELBE Haus zeigen. Sprich soll es sowas wie ein Postnachsendeantrag sein, dass beide Adressen bei einem Haus landen oder sollen es zwei verschiedene Haeuser sein, die sich nur gleichen?

    Fuer den ersten Fall brauchst du nichtmal Speicher reservieren. Da wuerde reichen:

    char *myHouse = "Haus!";
    char *myOtherHouse;
    myOtherHouse = myHouse;
    

    Wenn du jetzt aber myHouse einreisst, dann ist myOtherHouse auch weg (weil es ja das selbe war).

    Im zweiten Fall:

    char *myHouse = "Haus!";
    char *myOtherHouse = new char[strlen(myHouse) + 1];
    strcpy(myHouse, myOtherHouse);
    

    Das +1 kommt daher, dass strlen das Abschlusszeichen '\0' nicht mitzaehlt, du musst aber das Zeichen mitkopieren weil man sonst das Ende nicht erkennt.

    Hoffe mal ich konnte dir irgendwie helfen 😉

    so far

    Phil



  • und dann noch was echt merkwürdiges ich hol mit doch gar kein speicher oder halt 0 Speicher aber es geht alles wie immer warum das???macht des dann der compiler autoamtisch???
    wenn ich aber die zeile komplett weg lasse kommt dein Kompileriungsfehler aber beim ausführen "Segmentation fault" ist ja au klar also holt er doch net automatisch speicher aber mit 0 speicher holen geht es oder wie??? blick ich au net
    😞

    Durch den Aufruf von new wird auch Speicher für andere Sachen reserviert und im Debug-Modus kommt noch dazu, das der Compiler noch auf Heap-Overflow's überprüft. Außerdem darfst du immer auf eine komplette Speicherseite(4 KB groß) Zugriff und diese wird beim Aufruf von new bereitgestellt, das ganze ist aber irrelevant.
    Der Speicher den du also beschreibst, gehört eigentlich gar nicht dir. Bei diesem simplen Programm führt das noch nicht zu einem Fehler, da es ja sofort danach beendet wird, aber bei größeren Programmen, würdest du damit unweigerlich den Heap korrumpieren und es stürtzt ab.

    MfG
    DDR-RAM



  • oli23 schrieb:

    und dann noch was echt merkwürdiges ich hol mit doch gar kein speicher oder halt 0 Speicher aber es geht alles wie immer warum das???

    Sowas nennt man undefiniertes Verhalten. Dh passieren kann alles, korrekt ist es trotzdem nicht. Bei

    new char[0]
    

    wird trotzdem eine gültige Adresse zurückgegeben, auch wenn dir kein Bit Speicher dort gehört. Dass in deinem Beispiel trotzdem genügend vorhanden ist, liegt einfach daran, dass der Speichermanager immer entsprechend grosse Blöcke zur Verfügung hat.



  • Aber den Speicher muss ich doch auch noch freigeben mit delete oder?

    also so allokieren
    Buffer= new char[groeße];

    und so freigeben

    delete Buffer;

    ist ja im vergleich zu c und malloc recht einfach 🙂



  • oli23 schrieb:

    Aber den Speicher muss ich doch auch noch freigeben mit delete oder?

    Exakt

    oli23 schrieb:

    also so allokieren
    Buffer= new char[groeße];

    und so freigeben

    delete Buffer;

    Fast.

    delete[] Buffer
    

    ist korrekt, da du ja ein Array hast. Ohne die [] loeschst du nur das Objekt was direkt unter dem Zeiger liegt.

    oli23 schrieb:

    ist ja im vergleich zu c und malloc recht einfach 🙂

    Buffer = malloc(size);
    free(Buffer);

    Is doch auch nicht schwerer 😉



  • groovemaster schrieb:

    oli23 schrieb:

    und dann noch was echt merkwürdiges ich hol mit doch gar kein speicher oder halt 0 Speicher aber es geht alles wie immer warum das???

    Sowas nennt man undefiniertes Verhalten. Dh passieren kann alles, korrekt ist es trotzdem nicht. Bei

    new char[0]
    

    wird trotzdem eine gültige Adresse zurückgegeben, auch wenn dir kein Bit Speicher dort gehört. Dass in deinem Beispiel trotzdem genügend vorhanden ist, liegt einfach daran, dass der Speichermanager immer entsprechend grosse Blöcke zur Verfügung hat.

    Wobei noch anzumerken ist, dass der Zugriff auf ein solches Objekt UB erzeugt.

    mfg
    v R


Anmelden zum Antworten