²²²² bei dyn Speicherreservierung



  • Hallo, ich hab mal eine Frage bezüglich dynamischer Arrays:
    Also, ich habe mir wie folgt eine Klasse geschrieben, mit der ich ein dynamisches char-array erzeuge. Sie hat die Funktionen Push zum hinzufügen eines neuen 'char' und die Funktion GetArray() mit der dann das gesamte
    Feld zurückgegeben werden soll. Sie Funktionsdefinitionen sehen dabei so aus :

    charlist::charlist()	//Constructor
    {
    	position=0;
    	size=1;
    	array=new char[size];
    }
    charlist::~charlist()	//Destructor
    {
    	position=0;
    	size=0;
    	delete[] array;
    	if(tmp_array)
    		delete[] tmp_array;
    }
    
    void charlist::Push(char c)
    {
    	array[position]=c;
    	tmp_array=new char[size];
    	for(int i=0;i<size;++i)
    	{
    		tmp_array=array[i];
    	}
    	++size;
    	++position;
    	array=new char[size];
    	for(int j=0;j<size-1;++j)
    	{
    		array[j]=tmp_array[j];
    	}
    }
    char* charlist::GetArray(void)
    {
    
    	return tmp_array;
    }
    

    Jetzt lass ich in der int main mit einer schleife 10x ein 'a' hinzufügen und gebe dann das feld aus. Es erscheint dann in der tat 10x das 'a', allerdings
    dahinter noch "²²²²" . Mit diesen Zweien kann ich nicht viel anfangen, ich vermute, dass ich einen Speicherbereich anzeige, den ich nicht mit Werten
    belegt habe, aber ich weiss es nicht genau. Vielleicht könnt ihr mir da helfen ?
    Ich brauche das dynamische array nämlich, um einen Text aus einer datei einzulesen. dabei ist es wichtig, dass der text als ganzes in einem Array gespeichert wird.
    Und da ich nicht so ein brutaler Speicherverschwender bin 😉 , wollte ich das ganze dynamisch angehen.
    Also, ich hoffe, ihr könnt mir helfen (is ja sowieso recht regnerisch heut nachmittag).

    Gruß & Vielen Dank
    [i]E-the-Real*



  • Du weißt aber schon das es std::vector gibt, oder?



  • Ja, is mir schon klar, aber ich wollte mir halt selber mal sowas schreiben, da ich mit Speicherreserv. auch noch nicht so vertraut bin.



  • hallo!
    wenn du dein char array ausgeben willst, musst du auch irgendwie bekannt machen, wo es aufhört: ohne begrenzung wird einfach so lange weiter ausgegeben, bis zufällig mal ein '\0' kommt. '\0' ist normalerweise das letzte zeichen einer solchen zeichenkette.
    das heißt:
    1)

    char_list_obj.Push('\0');
    

    und dann ausgeben, oder:
    2)

    cout << std::string(char_list_obj.Get_Array(), char_list_obj.size());
    

    hat beides denselben effekt: ein '\0' zeichen als zeichen für das ende des strings wird angehängt.

    was mir an deinem code noch auffällt:
    du hast ein bisschen viele news im vergleich zu deinen deletes 😉
    außerdem: bei jedem push_back gleich soviel speicher neu zu allozieren wirkt sich sicher irgendwann einmal auf die gesamtperformance aus.
    schau dir einmal eine vector implementierung an zb. da kann man viel lernen.



  • @davie:
    Hey, Vielen, vielen Dank !
    Es ist zwar banal, dass ich das EOF explizit angeben muss, aber ich bicn da echt nicht drauf gekommen.
    Noch eine Frage zu den "news": meinst du, es ist klüger, delete schon in der Push-Funkt. aufzurufen ?

    Und zu der Vec-Impl: wo finde ich denn Vector-Implementierungen ?

    Nochmals Dankeschön & Gruß
    E-the-Real



  • zu den news

    void charlist::Push(char c)
    {
    	array[position]=c;
    	tmp_array=new char[size]; //wenn du push jetzt ein 2. mal
            //aufrufst, dann zeigt tmp_array doch noch immer auf den hier allokierten speicher: deshalb: am ende der funktion delete [] tmp_array
            //dann muss tmp_array auch nicht mehr eine membervariable sein,
            //und kann hier eine lokale sein.
    
    	for(int i=0;i<size;++i)
    	{
    		tmp_array[i]=array[i];
    	}
    	++size;
    	++position;
            /* delete array */
    	array=new char[size];
            //hier genauso: du erzeugst neuen speicher und lässt den alten aber
            //unwiederruflich zurück.
    
    	for(int j=0;j<size-1;++j)
    	{
    		array[j]=tmp_array[j];
    	}
            /* delete [] tmp_array; */
    }
    

    du könntest zb. im konstruktor alle zeiger auf 0 setzen, und dann den code aus
    push wie hier mit den 2 delete übernehmen.
    aber wie gesagt wäre es dann ebenfalls noch lange nicht eine optimale version.

    zugegeben, etwas kompliziert und quer ausgedrückt: vector implementation von sgi
    aber google hilft hier sicher 🙂


Anmelden zum Antworten