Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Zeiger für Dummies

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
11.02.2010, 17:11 Uhr
banshee




C++:
#include <iostream>

int main(int argc, char* argv[])
{
    char * data=new char[3];
    data[0] = 'A';
    data[1] = 'B';
    data[2] = 'C';
    char *stream=data;

    *stream = *stream + 1;
    std::cout << *stream;
}


Dieses Programm gibt wie gewünscht B aus. Da *stream auf data zeigt, müsste folgendes Programm doch eigentlich äquivalent sein:


C++:
#include <iostream>

int main(int argc, char* argv[])
{
    char * data=new char[3];
    data[0] = 'A';
    data[1] = 'B';
    data[2] = 'C';
    char *stream=data;

    data = data + 1;
    std::cout << data;
//std::cout << *stream;
}


Jetzt bekomme ich aber nur Speichermüll ausgegeben. Wenn ich die darunterliegende Anweisung einkommentiere, gibt es wieder A aus.

Kann mir irgendwer erklären, was da vor sich geht?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
11.02.2010, 17:42 Uhr
Guybrush Threepwood
Gefürchteter Pirat
(Operator)


C-Strings also char Arrays werden mit einer binären Null abgeschlossen damit man weiß wo er endet.
Das erste Programm funktioniert weil du *stream an cout übergibst. Du derefernzierst den Zeiger also bereits und gibst ein char an cout was dieses ausgibt. In dem Fall also das 'B'
Im zweiten Programm übergibst du data an cout also einen char*. cout gibt also kein einzelnes Zeichen sondern eine Zeichenkette aus und da die 0 am Ende fehlt weiß es nicht wo schluss ist und gibt so lange den Speicherinhalt aus bis eine 0 kommt oder das Programm aufgrund einer Zugriffsverletzung abstürzt.

Dieser Post wurde am 11.02.2010 um 17:42 Uhr von Guybrush Threepwood editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
12.02.2010, 11:13 Uhr
banshee



Okay, leicht modifiziertes Programm:


C++:
#include <iostream>

int main(int argc, char* argv[])
{
    char * data=new char[4];
    data[0] = 'A';
    data[1] = 'B';
    data[2] = 'C';
    data[3] = '\0';
    char *stream=data;

    *stream = *stream + 1;
    //std::cout << data;
    std::cout << *stream;
}


stream ist doch ein double pointer, also müsste ich cout doch einen Zeiger auf char geben und das dementsprechend BC ausgeben?!

Interessant ist auch das hier:


C++:
#include <iostream>

int main(int argc, char* argv[])
{
    char * data=new char[4];
    data[0] = 'A';
    data[1] = 'B';
    data[2] = 'C';
    data[3] = '\0';
    char *stream=data;

    data = data + 1;
    std::cout << data << std::endl;
    std::cout << *stream;
}


Wenn ich einen double pointer definiere und den inneren Zeiger verändere, bleibt der äußere davon völlig unbeeindruckt?!

Ich hatte mir das so vorgestellt, dass man *stream an jeder beliebigen Stelle durch data ersetzen kann, weil beides äquivalent sein müsste.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
12.02.2010, 14:17 Uhr
0xdeadbeef
Gott
(Operator)



C++:
    char *stream=data;


Wo siehst du da einen Doppelzeiger?

Kann es sein, dass du eigentlich

C++:
  char **stream = &data;


meinst?

Übrigens: Du solltest den angeforderten Speicher wieder freigeben (oder gleich ein Stack-Array benutzen).
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra

Dieser Post wurde am 12.02.2010 um 14:18 Uhr von 0xdeadbeef editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
12.02.2010, 18:48 Uhr
banshee



hm, ich dachte data ist ein Zeiger auf eine Zeichenkette und Stream ein Zeiger auf einen Zeiger auf eine Zeichenkette, also Doppelzeiger oder nicht?

Der Originalausschnitt sieht übrigens so aus:


C++:
FILE *in=fopen(file,"r");
    if (in)
    {
        fseek(in,0,SEEK_END);
        int size=ftell(in);
        fseek(in,0,SEEK_SET);
        char * data=new char[size];
        fread(data,1,size,in);
        fclose(in);
        char *stream=data;
        XMLNode *out=new XMLNode(&stream);
        delete [] data;
        return out;
    }
    return NULL;
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
12.02.2010, 19:03 Uhr
0xdeadbeef
Gott
(Operator)


Eine Datei liest du einfacher in einen String als

C++:
#include <fstream>
#include <iterator>
#include <string>

// ...

std::ifstream in(file);

std::string data(std::istreambuf_iterator<char>(in.rdbuf()),
                 std::istreambuf_iterator<char>());


Die XMLNode-Klasse ist mir jetzt nicht bekannt, aber es sollte mich irgendwie wundern, wenn eine C++-Klasse einen String als char** erwartete. Um welche Bibliothek handelt es sich da?
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
13.02.2010, 12:05 Uhr
banshee



Ja, dass das eleganter geht, hab ich mir schon gedacht. Es handelt sich dabei aber wieder um Fremdcode, den ich bei der Gelegenheit gleich verstehen möchte

Die XMLNode Klasse ist auch eine Eigenimplementierung, deshalb nimmt sie auch nen char**.

Fangen wir doch mal ganz grundlegend an: Wo ist denn hier der Unterschied


C++:
#include <iostream>

int main(int argc, char* argv[])
{
    char * data=new char[4];
    data[0] = 'A';
    data[1] = 'B';
    data[2] = 'C';
    data[3] = '\0';
    char *stream=data;
    char **stream2 = data;
}


stream2 deklariere ich jetzt explizit als Zeiger auf Zeiger. stream ist nur als einfacher Zeiger deklariert, zeigt aber eben auch auf einen Zeiger. So gesehen sind das doch beides Doppelzeiger. Worauf greife ich jetzt also mit *stream und *stream2 zu?

Dieser Post wurde am 13.02.2010 um 12:05 Uhr von banshee editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
13.02.2010, 12:22 Uhr
0xdeadbeef
Gott
(Operator)


Du meinst

C++:
char **stream2 = &data;


& nimmt die Adresse eines Symbols, in diesem Fall also einen Zeiger auf data. Data seinerseits ist ein Zeiger auf Zeichen, und so ist stream2 ein Zeiger auf einen Zeiger auf Zeichen.


C++:
char *stream = data;


dagegen nimmt eine Kopie von data, also einen Zeiger auf Zeichen, und schreibt diesen in stream.

Ich nehme an, dass im Codebeispiel oben der Konstruktor von XMLNode den übergebenen Zeiger verändert, weswegen eine Kopie von data und nicht data selbst übergeben wird (data selbst wird unverändert zur Speicherfreigabe benötigt).
--
Einfachheit ist Voraussetzung für Zuverlässigkeit.
-- Edsger Wybe Dijkstra
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
14.02.2010, 12:11 Uhr
banshee



aaaaach...

Ich bin irgendwie davon ausgegangen, dass data ein char-Array ist und man mit char *stream = data nicht einfach den Zeiger kopiert sondern auf die Feldadresse zugreift. So ergibt das natürlich alles wunderbar Sinn
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: