Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Unterschied new malloc delete free

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
04.08.2006, 20:16 Uhr
~Blubber2063
Gast


Tach, hab mich mal wieder mit c++ beschäftigt und mir ist folgende Frage aufgekommen, die mich doch irgendwie brennend interessiert. Nach C Standard wird speicher ja mit malloc, etc auf dem heap alloziert, sprich BS weist einem freien Speicher zu. Analog denke ich funktioniert der new Operator in C++, der das dann wrappen wird. Aber wie ist das mit dem free, delete Unterschied. free gibt ja den vorher auf dem allozierten speicherbereich wieder frei, sprich den Zeiger von Malloc, das BS merkt sich ja hier eigentlich intern wie gross der Bereich war der alloziert wurde. In C++ gibt es ja aber den Operator delete [], woher weiss der wie gross das allozierte Feld war, das ist ja eigentlich nur dem BS bekannt, denn die Größe eines dynamischen Feldes ist ja nur durch eigenes merken feststellbar. Haben C++ Programme eine eigene Speicherverwaltung um weniger Speicheranfragen an das BS zu stellen oder gibt es eine standardiesierte BS Funktion die bei angabe eines allozierten Speichereichs die Größe der Anforderung zurückgibt ?

Gruß Blubber
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
05.08.2006, 10:12 Uhr
virtual
Sexiest Bit alive
(Operator)


Hallo,

erstmal macht new doch deutlich mehr, als malloc. malloc belegt, wie Du bereits richtig bemerkst, Speicher. new hingegen belegt Speicher und ruft den Constructor einer Klasse auf (im Falle eines Primitives, zB int ist der Aufruf des Constructors natürlich eine null Operation).
Analog ruft delete zunächst den Destructor auf und gib dann den Speciher frei, free gibt nur den Speicher frei.

Die beiden Schritte (allozierung/Konstruieren bzw. Destruieren/freigabe) kann man mit Hilfe von Allocatoren übrigens getrennt aufrufen.

Im Falle von Arrays ists nun so, daß man für alle Elemente im Array den Konstruktor (new[]) bzw. Destruktor (delete[]) aufrufen muß, daher sind new[] und new eben unterschiedliche Dinge.

Generell gibt es keine standardisierte, dh Portable, Möglichkeit, die Größe des belegten Speichers oder gar die Anzahl der Array elemente zu bestimmen, jedoch gibt es Systemabhängige Lösungen für dieses Problem.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
05.08.2006, 10:14 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi, im Endeffekt kann man (im großen und ganzen)

malloc mit new gleichsetzen, und free mit delete[]

Natürlich gibts es kleinere Unterschiede, u.A das delete und new keine Funktionen im eigentlichen Sinn sind, sondern operatoren.

Es läuft immer darauf hinaus, das malloc z.B. mit brk/sbrk das Datensegment vergrößert, (normal holt sich die funktion direkt ein vielfaches von einer page, also wenn du jetzt 100x 2Byte mallocst, holt es sich beim ersten z.B. 4096kb und gibt dir das dann stück für stück) dann natürlich erst seine Verwaltungstrukturen (wie immer die auhc aussehen mögen) reinschreibt und dann eben einen Speicheradresse zurückliefert an dem du nun die Menge Bytes frei hast die du wolltest. Im Endeffekt macht new auch nichts anderes.

imho weiß free und delete erstmal nicht wie groß der Speicher war und ob der Pointer darauf auch überhaupt gültig ist weiß es auch nicht

z.B.


C++:
int a;
int *b  = &a;
delete b;



fliegt einen um die Ohren, gleiche Spiel mit free.

delete und free geben (bzw versuchen es zumindest) eben den Bereich frei, indem sie in der Verwaltungsstruktur davor oder dahinter den Bereich als frei markieren, und normalerweise passieren dann noch komplexere dinge, z.b defragmentierung der freien bereiche, usw, ist kompliziert und meist für normaluser uninteressant (den mist lernt man alles im 2ten semester informatik studium )
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.08.2006, 12:47 Uhr
~Blubber2063
Gast


Öhmm, ja gut, das mit dem Konstruktor in new bzw destructor bei delete war klar, ich studiere Informatik und beginne im Oktober mein 5. Semester, hab auch schon so einige Ahnung von BS etc, was ich eigentlich wissen wollte, hab ich vielleicht doof formuliert, ist, woher delete [], die Größe des Feldes bezieht, denn er muss sie ja kennen um für jedes Objekt den Destructor aufzurufen.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.08.2006, 13:26 Uhr
J-jayz-Z
Perl Crack ala Carte
(Operator)


Es wird intern einfach über jedes Element iteriert, bis eben kein Objekt mehr da ist, dessen Speicher er löschen soll.Wenn du die Inhalte eine beispielsweise Vectors durchläufst, weißt du ja auch nicht, wie groß er ist und kannst trotzdem mit einem iterator jedes Element durchlaufen - eben biskeinsmehr da ist !
--
perl -Mstrict -Mwarnings -e 'package blub; sub new { bless {} } sub bar {my $self=shift; $self->{bla}="66756e2d736f66742e6465"; return $self->{bla};} my $foo=blub->new();print "Hallo ";print pack("H*",$foo->bar()); print "\n"'
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
05.08.2006, 13:32 Uhr
~Blubber2063
Gast


Das würde ich anders sehen, korrigiert mich wenn ich falsch liege, aber es ist doch so ein Vektor ist eine Klasse die intern ein Feld implementiert, das sich bei bedarf, selbst vergrößert, also realloc(oder ähnliche Realisierung) macht, wobei seine Größe und die Anzahl der Elemente als Elemente der Klasse ebenso enthalten ist und da er Teil der STL ist, kann man ihn mit den Iteratoren durchlaufen. Aber ein Feld an sich ist ein Bereich im Speicher der hintereinander steht, wenn du jetzt weitergehts als der Speicher dort vorhanden ist, gibts eigentlich von der MMU ne synchrone Unterbrechung, die das BS(sofern die Sig Handler nicht überschrieben wurden) mit einem Segfault quittiert, es sie denn der Speicher hinter dem Feld gehört dir zufälliger Weise auch, wobei du dann evtl. deine eigenen Daten vernichtest. Also die Freigabe des Speichers des Feldes ist ja kein Problem, aber für die Destruktor Aufrufe muss delete ja wissen wie gross das Feld ist.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
05.08.2006, 14:16 Uhr
virtual
Sexiest Bit alive
(Operator)


Hallo,

also new und malloc belegen meist etwas mehr Platz als eigentlich angefordert wurde. In den ersten Bytes Speichern sie die Länge des belegten speichers und geben dann einen Zeiger auf die Stelle dahinter als belegten Speicher zurück. D.h. denkbar ist folgendes:

C++:
#include <iostream>

class myclass {
        char x[1000];
};

int main() {
        myclass* str = new myclass;

        std::cout<<"Address of str: "<<str<<std::endl;
        std::cout<<"sizeof(*str):   "<<sizeof(*str)<<std::endl;

        int* memptr = (int*)str;
        std::cout<<"Controldata: "<<memptr[-1]<<std::endl;
}


Kompilierst Du dieses Programm mit einem g++, so wird mit memptr[-1] immer eine Gräße zurückgegeben, welche von der Größe des belgten Speichers abhängt. Dh mit diesen Kontrolldaten, welche normalerweise nicht sichtbar sind (und je nach Laufzeitlib unterschiedlich umgesetzt werden) kann entschieden werden, wie groß das Array ist usw.

Was die Verwendung von realloc in std::vector angeht, da muß ich die Enttäuschen: ist der Speicher tatsächlich zu klein, wird gnadenlos jedes Element im Vector neu angelegt. Allerdings bedient sich der Vector allocatoren, die - wie in Post 001 angedeutet - Speicherbelegung und Konstruktion der Objekte in zwei einzelnen Schritten ausführen und die ganze Sache zumindestens teilweise wieder optimieren.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
007
05.08.2006, 14:32 Uhr
~Blubber2063
Gast


Thx, das war genau das was ich wissen wollte, das mit dem Vektor ist gut zu wissen, ich war jetzt mal davon ausgegangen, das die Implementation dem Java Vector ähnlich ist, der sich automatisch um eine vorgegebene Größe vergrößert, wenn er überlaufen würde.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
008
05.08.2006, 15:35 Uhr
(un)wissender
Niveauwart


Der Java Vector verhält sich bei der Vergrößerung wie der C++ Vector. Nur speichert der Java Vector Referenzen und ist synchronisiert. Der C++ Vector speichert Werte und ist nicht synchronisiert.
--
Wer früher stirbt ist länger tot.
 
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: