C malloc() und free()?

3 Antworten

Das zweite was du hier verwendest bezeichnet man als Variable Length Array (VLA) und das unterstützen viele (aber nicht alle) Compiler sofern man die Sprachversion nach oben dreht, allerdings haben VLAs einige gravierende Probleme weswegen sie zB nicht im C++ Standard aufgenommen wurden. Ein oft genannter Grund dafür ist, dass sizeof bei einem VLA nicht zur Compiletime bekannt ist womit das in C++ eben nicht mehr eindeutig für constexpr genutzt werden kann.

Ein VLA hat zudem keinen Vorteil gegen malloc/free außer dass das Array vielleicht am Stack reserviert wird was aber eigentlich eher mehr Probleme bereitet als am Heap.

Zudem ist das Prüfen auf eine fehlerhafte Allozierung mit malloc weitaus einfacher. Also mit einem VLA bekommst du direkt einen Segmentation Fault während malloc dir den Nullpointer zurück gibt.

Der allgemeinere Code wäre also die Verwendung von malloc und free ohne VLAs.

VLAs sind vielleicht bei garantiert sehr kleinen Arrays nützlich, weil dann der Impact auf den Stack nicht all zu groß ist und sie haben in C den Vorteil dass man hier ein explizites free braucht, weil das der Compiler macht.

Allerdings kann man wenn man in C malloc und free oder VLAs verwendet auch direkt C++ verwenden und hier mit Smartpointern arbeiten was dann den selben Effekt hat nur dass man hier eben auf dem Heap arbeitet. Also mir würde kein Fall einfallen welcher die Nutzung von VLAs notwendig oder besser machen würde.

Das zweie Beispiel funktionier nur, wenn

  • Der C-Compiler Felddeklarationen unterstützt, bei denen die Feldgröße keine Konstante ist. Bei int arr1[n1] ist n1 zur Übersetzungezeit nicht bekannt.
  • Der C-Kompiler Deklarationen nach ausführbaren Anweisungen erlaubt. Nach scanf darf keine Deklaration mehr kommen.

Manche neueren C-Compiler erlauben so etwas, aber selbstverständlich ist das nicht.

In c kannst du keine Variablen als Arraygröße in der Deklaration benutzen. Ab C99 war das teilweise möglich, aber die Fehlerquote bei denen, die das dann verwendeten, war enorm, weil sie keine Fehlerbehandlung machen.


Butzti 
Fragesteller
 03.03.2022, 15:22

Echt? Weil beide Code-Abschnitte funktionieren bei mir

0
priesterlein  03.03.2022, 15:24
@Butzti

Dann hast du einen Compiler, der das kann, das war aber nicht immer so und wie man sieht, neigst auch du dazu, komplett alle potentiellen Fehler zuzulassen.

0
Butzti 
Fragesteller
 03.03.2022, 15:24
@tunik123

Okay, also sollte ich bei solchen Problemen eher mit malloc() arbeiten, oder?

0
priesterlein  03.03.2022, 15:26
@Butzti

Wenn du absolut C-treu sein willst, musst du wissen, dass ALLE Deklarationen am Anfang eines Blockes stehen müssen und das gibt dein code nun mal in beiden gezeigten Beispielen nicht her. Also musst du sehr genau darauf achten, welche Compiler du verwendest und wie sie genau damit umgehen. Wenn sie das alles können und du nicht wechselst: ok. Aber passe trotzdem auf, in der Programmierung IMMER Fehler abzufangen, Grenzwerte zu kontrollieren usw.

2
tunik123  03.03.2022, 15:30
@Butzti

Ja, wenn es portabel sein soll, lieber mit malloc().

0