Speicher am Heap in einer Funktion freigeben?



  • @SeppJ sagte in Speicher am Heap in einer Funktion freigeben?:

    wenn ich printf mit cout ersetze und malloc mit new ist das doch C++?

    Tu die ++ weg.



  • @ledi001 sagte in Speicher am Heap in einer Funktion freigeben?:

    Ich bin gerade dabei C++ zu lernen, daher spiele ich derzeit mit Arrays bzw. Array-Pointern herum.

    Spiele lieber mit std::vector herum! Schau mal hier: https://en.cppreference.com/w/cpp/container/vector
    Ein Pointer ist ein Pointer und kein Array.
    Ein Array ist ein Array und kein Pointer.
    Ein Array kann automatisch in einen Pointer zerfallen (konvertiert werden). Umgekehrt nicht.



  • Und selbst wenn man keinen std::vector möchte, würde man keinen rohen Zeiger nehmen:

    #include <cstddef>
    #include <memory>
    #include <algorithm>
    
    auto foo(int value, std::size_t length)
    {
    	auto bar{ std::make_unique<int[]>(length) };
    	std::fill(bar.get(), bar.get() + length, value);
    	return bar;
    }
    

    Aber wahrscheinlich die Parameter umdrehen und ein Default vorgeben:

    #include <cstddef>
    #include <memory>
    #include <algorithm>
    
    template<typename T>
    auto foo(std::size_t length, T value = T{})
    {
    	auto bar{ std::make_unique<T[]>(length) };
    	std::fill(bar.get(), bar.get() + length, value);
    	return bar;
    }
    

    `



  • @SeppJ sagte in Speicher am Heap in einer Funktion freigeben?:

    Und auch in unmordernem C++ nicht. Eine der Hauptmotivationen für das Design von C++ war, die unsägliche manuelle Ressourcenverwaltung von C loszuwerden.

    Das ist historisch falsch. Die STL wurde erst relativ spät kreiert und wurde dann erst mit C++ 1998 Teil der Sprache. Die Verwendung von new und delete waren also vor C++ 1998 der Standard und nicht die Ausnahme. Da aber die Autopointer Klasse in C++ 1998 kaputt war, musste man noch viele Jahre auf die Verwaltung Resourcen in den eigenen Klassen setzen. Erst das Boost Projekt hat kann funktionierende Smart Pointer geliefert, die dann erst mit C++ 2011 Teil der Sprache wurden.


  • Mod

    @john-0 sagte in Speicher am Heap in einer Funktion freigeben?:

    @SeppJ sagte in Speicher am Heap in einer Funktion freigeben?:

    Und auch in unmordernem C++ nicht. Eine der Hauptmotivationen für das Design von C++ war, die unsägliche manuelle Ressourcenverwaltung von C loszuwerden.

    Das ist historisch falsch. Die STL wurde erst relativ spät kreiert und wurde dann erst mit C++ 1998 Teil der Sprache. Die Verwendung von new und delete waren also vor C++ 1998 der Standard und nicht die Ausnahme. Da aber die Autopointer Klasse in C++ 1998 kaputt war, musste man noch viele Jahre auf die Verwaltung Resourcen in den eigenen Klassen setzen. Erst das Boost Projekt hat kann funktionierende Smart Pointer geliefert, die dann erst mit C++ 2011 Teil der Sprache wurden.

    Und was haben STL und Autopointer damit zu tun? Lies dir die Interviews mit Stroustrup durch, bevor du hier anderen historische Fälschung vorwirfst. Alleine die Möglichkeit, das man in C++ die STL und Autopointer haben kann, zeigt dass die automatischen Destruktoren essentieller Teil des Sprachdesigns sind.



  • @Swordfish sagte in Speicher am Heap in einer Funktion freigeben?:

    std::size_t ftw.

    ...wohl eher ein Designfehler in der C++ Standard Bibliothek :o)



  • @HarteWare Da scheiden sich die Meinungen der Geister.



  • @SeppJ sagte in Speicher am Heap in einer Funktion freigeben?:

    Und was haben STL und Autopointer damit zu tun? Lies dir die Interviews mit Stroustrup durch, bevor du hier anderen historische Fälschung vorwirfst. Alleine die Möglichkeit, das man in C++ die STL und Autopointer haben kann, zeigt dass die automatischen Destruktoren essentieller Teil des Sprachdesigns sind.

    Templates wurden erst mit Cfront 3.0 eingeführt, das ist die letzte Version vor der ISO Norm und Basis der 2. Auflage von „The C++ Programming Language, 1991“. Das wurde aber auch erst Realität, weil unter anderem Alexander Stepanov (der wesentliche Schöpfer der STL) sehr stark darauf hin gearbeitet hat, und Ada artige generische Programmierungsfähigkeiten in C++ haben wollte. Die STL hatte nämlich mit den Booch Components (die Ada 83 Version) so etwas wie einen Vorgänger. D.h. so groß auch die Verdienste von Stroustrup bei der Erschaffung von C++ sind, der ganze Themenkomplex generische Programmierung wurde an ihn heran getragen und ist nicht auf seiner Initiative heraus entstanden.

    D.h. es gab zwar RAII seit der ersten Version von C++ (Cfront 1.0, 1985), aber weder Exceptions noch Templates in dieser frühen Form von C++. D.h. es waren weder Smart Pointer noch Container wie std::vector möglich.

    P.S. Das ist im Buch „Design and Evolution of C++“ nachlesbar, was man eigentlich als C++ Crack schon einmal gesehen haben sollte.



  • @john-0 sagte in Speicher am Heap in einer Funktion freigeben?:

    was man eigentlich als C++ Crack schon einmal gesehen haben sollte.

    Weder @SeppJ noch ich sind "C++ Crack"s. Aber wir wissen meistens, wovon wir reden. Wo du die Grenze zwischen modernem C++ und unmodernem ziehst ist mir herzlich schnuppe.


  • Mod

    @john-0 sagte in Speicher am Heap in einer Funktion freigeben?:

    @SeppJ sagte in Speicher am Heap in einer Funktion freigeben?:

    Und was haben STL und Autopointer damit zu tun? Lies dir die Interviews mit Stroustrup durch, bevor du hier anderen historische Fälschung vorwirfst. Alleine die Möglichkeit, das man in C++ die STL und Autopointer haben kann, zeigt dass die automatischen Destruktoren essentieller Teil des Sprachdesigns sind.

    Templates wurden erst mit Cfront 3.0 eingeführt, das ist die letzte Version vor der ISO Norm und Basis der 2. Auflage von „The C++ Programming Language, 1991“. Das wurde aber auch erst Realität, weil unter anderem Alexander Stepanov (der wesentliche Schöpfer der STL) sehr stark darauf hin gearbeitet hat, und Ada artige generische Programmierungsfähigkeiten in C++ haben wollte. Die STL hatte nämlich mit den Booch Components (die Ada 83 Version) so etwas wie einen Vorgänger. D.h. so groß auch die Verdienste von Stroustrup bei der Erschaffung von C++ sind, der ganze Themenkomplex generische Programmierung wurde an ihn heran getragen und ist nicht auf seiner Initiative heraus entstanden.

    D.h. es gab zwar RAII seit der ersten Version von C++ (Cfront 1.0, 1985), aber weder Exceptions noch Templates in dieser frühen Form von C++. D.h. es waren weder Smart Pointer noch Container wie std::vector möglich.

    P.S. Das ist im Buch „Design and Evolution of C++“ nachlesbar, was man eigentlich als C++ Crack schon einmal gesehen haben sollte.

    Nochmal: Und? Templates haben rein gar nichts mit RAII zu tun, welches, wie du selber bestaetigst, in der ersten Version drin war, und, wie ich dir schon gesagt habe, eine der Hautpmotivationen fuer C++ war.



  • Was aber bestätigt dass man vor der STL jedoch trotzdem das nackte new verwendet hat.


  • Mod

    Aber von der STL habe ich doch gar nicht geredet! Es gibt Ressourcenverwaltung jenseits der STL! Die STL hat bloß das, was jeder vorher von Hand geschrieben hat, in wiederverwertbareTemplates verpackt, nachdem die Templates erfunden wurden.



  • Ihr redet glaube ich aneinander vorbei.
    Das Eingangsbeispiel mit dem new in einer Funktion war auch mit Uralt-C++ nicht gut.
    Dafür hätte man sich halt -mangels STL- eine Klasse gebastelt (RAII), die dann tief unten drin auch irgendwann ein new/delete benötigt hätte.



  • @john-0 Ich glaube du verwechselst hier manuelle Resourcenverwaltung mit selbst geschriebenen RAII Klassen. Selbst geschriebene RAII Klassen braucht man sogar mit C++17 noch öfters, da es z.B. noch kein unique_resource Template in der Standard Libaray gibt, und nicht jeder "Resource-Identifier" ein Zeiger ist.

    Natürlich wäre es auch schön wenn man für so einfache Dinge wie "Socket Handle freigeben" keine eigenen Klassen mehr schreiben müsste. Der wichtigste Punkt ist aber dass man diese Klassen schreiben kann - und dann schön mit z.B. Sockets arbeiten kann ohne dass man an zig oder hunderten Stellen die Funktion zur Freigabe der Resourcen selbst aufrufen muss. Und das konnte C++ von Anfang an. Nicht so schön wie dann später mit Templates, aber es ging. Und das ist es was zumindest ich darunter verstehe wenn jemand schreibt "manuelle Ressourcenverwaltung von C loswerden".



  • @spiri sagte in Speicher am Heap in einer Funktion freigeben?:

    Was aber bestätigt dass man vor der STL jedoch trotzdem das nackte new verwendet hat.

    Und auch mit der STL verwendest du noch "nackte" Resource-Allokations-Funktionen irgendwo im Code. Idealerweise aber nur in einer Klasse, nämlich der RAII-Wrapper Klasse (oder einer Factory o.Ä.), aber selbst aufrufen tut man sie. Und das wird auch so bleiben, denn der C++ Standard wird nie sämtliche Arten von Resourcen abdecken die man von irgendwelchen (C-)Libraries bekommen kann.



  • @Swordfish sagte in Speicher am Heap in einer Funktion freigeben?:

    Weder @SeppJ noch ich sind "C++ Crack"s. Aber wir wissen meistens, wovon wir reden. Wo du die Grenze zwischen modernem C++ und unmodernem ziehst ist mir herzlich schnuppe.

    C++ ist eine historisch gewachsene Sprache, und viele der Paradigmen haben sich verändert. Man kann das ignorieren und mit aktuellen C++ exzellente Programme schreiben, aber dann darf man sich nicht wundern, wenn man viele Dinge die historisch gewachsen sind nicht versteht.

    Es ist nun einmal eine Tatsache, dass an Universitäten die Uhren etwas anders gehen wie in der freien Wirtschaft. Deshalb ist es nicht sonderlich verwunderlich, wenn die Skripte nicht auf dem aktuellen Stand sind. Ferner sollte man als Student auch einmal die manuelle Speicherverwaltung gelernt haben, damit man zumindest in der Lage ist Klassen zu schreiben, die das korrekt umsetzen. Sprachen wie Python, Java, … sind dazu nicht geeignet, und wenn auch kein C mehr gelehrt wird, ist die Auswahl dafür gering. Es stellt sich also die Frage, ob der Dozent nicht absichtlich die manuelle Speicherverwaltung in C++ nutzt, damit die Studenten diese überhaupt kennenlernen.

    Ist es daher sinnvoll immer wieder bei den hier anzutreffenden Fragen zur manuellen Speicherverwaltung darauf zu insistieren, dass std::vector und SmartPointer soviel besser in C++ seien und deshalb nur diese in Frage kämen?

    Ohne Frage ist in der täglichen Nutzung von C++ für die normale Anwendungsentwicklung eine sehr weise Entscheidung zuerst Container aus der Standard Library zu nutzen, wenn diese nicht mehr ausreichen auf SmartPointer zu setzen und erst dann wenn diese Mittel nicht mehr ausreichend sind auf eigene Speicherverwaltung zu setzen. Aber auch für diesen speziellen gibt es sehr gute Gründe. Gerade weil das so ist muss man als Anfänger auch diese Sprachmittel erlernen.

    Zum historischen Hintergrund
    Es gab zwar schon in C with Classes Destrukturen, aber vieles was wir heute von C++ kennen gab es damals nicht. D.h. es gab keine Kopierkonstruktoren, keine Zuweisungsoperatoren (nur die C Zuweisung erfolgte, d.h. elementweise Kopie), d.h. RAII in seiner heutigen Form wurde erst später möglich. Stroustrup hatte zwar schon den Gedanken die Resourcenverwaltung zu verbessern, aber erst im Laufe der diversen Iterationen von C++ reifte dies zum dem heute Bekanntem heran. Mindestens das sollte man wissen.

    Desweiteren war der SmartPointer (std::auto_ptr<>) in der ISO Norm von 1998 kaputt, so dass er gar nicht benutzt werden konnte. Es gibt dazu etliche Artikel von Sutter, Meyers, et al. in denen sie die Defizite dieser Template Klasse beschreiben. Erst im Laufe der Jahre nach 1998 wurde im Boost Projekt funktionierende SmartPointer entwickelt. Aus den Erfahrungen mit denselben wurde dann eine leicht abgewandelte Variante Teil der ISO Norm von 2011. Ja, erst so spät gab es in der Norm funktionernde SmartPointer.



  • @john-0

    Es ist nun einmal eine Tatsache, dass an Universitäten die Uhren etwas anders gehen wie in der freien Wirtschaft.

    Du hast eine falsche Vorstellung von der freien Wirtschaft.



  • @manni66 sagte in Speicher am Heap in einer Funktion freigeben?:

    Du hast eine falsche Vorstellung von der freien Wirtschaft.

    Ich denke nicht, an den Unis ist es zum Teil um Größenordnungen schlimmer. Ein Beispiel dazu. Ich hatte das Problem, dass ich von einem Professor Programmcode in Fortran77 bekam und darin ein Sprachkonstrukt aus Fortran66 (dieses Feature wird nur in alten Lehrbücher erklärt) verwendet wurde, dass bereits in Fortran77 als veraltet bezeichnet war. D.h. in einem Fortran77 Lehrbuch wird man dieses Feature nur finden, weil man es nicht nutzen soll. Die Pointe an der Geschichte das Programm ist komplett nach dem Jahr 2000 entstanden, und in der Zwischenzeit gab es Fortran90, Fortran95 und den neuen freien gfortran Compiler, d.h. keinerlei Grund mehr ein Fortran66 Sprachfeature zu nutzen.

    P.S. Die BLAS und LAPACK Referenzimplementation ist noch immer in Fortran77 geschrieben.



  • @john-0
    Ich habe an der Uni Java gelernt und das war zu einem Zeitpunkt, als man noch Probleme hatte, Bücher über dieses komische Java zu finden.

    Soviel zu deinen Verallgemeinerungen.



  • @Jockelx sagte in Speicher am Heap in einer Funktion freigeben?:

    @john-0
    Ich habe an der Uni Java gelernt und das war zu einem Zeitpunkt, als man noch Probleme hatte, Bücher über dieses komische Java zu finden.

    Und wie häufig wurde diese Vorlesung dann auf den aktuellen Java Stand angepasst?


Anmelden zum Antworten