Forum: PC-Programmierung malloc() Programm terminiert nicht


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Felix W. (catchup)


Bewertung
0 lesenswert
nicht lesenswert
Guten Abend,
ich bin derzeit dabei ein C Programm zu schreiben, um int Zahlen aus
einer Liste
einzulesen und zu sortieren. Meine Idee war die Listengröße in einer
Funktion auszulesen und dementsprechend den Speicher mit malloc() zu
reservieren. Anschließend soll dem reservierten Speicher die einzelnen
Elemente zugewiesen werden. Das Programm läuft nur terminiert es nicht.
Würde mich freuen, falls mir jemand weiterhelfen könnte.


Rückgabewert von fscanf() wurde beim ersten Aufruf der Funktion 
einlesen_size() schon aufgerufen und geprüft.
int *einlesen_array()
{
  int *array; //Pointer bzw. Array
  FILE *ptr; //Pointer der auf Beginn des Files zeigt
  int size = einlesen_size();  //dynamische Arrayanpassung als Laufvariable
  int i;
  
  //Pointer auf Beginn von Pfad definiert   
   ptr = fopen(pfad, "r");
  /********************************
   * Arraydefinition über malloc()*
   *******************************/
  array = (int *) malloc(size * sizeof(int));

  if (array == NULL)
  {
    printf("Speicher voll!\n");
    printf("Bitte Programm neustart.\n");
    return 0;
  }
  /**********************************
   * Füllen des Arrays mit Elementen*
   *********************************/
  for(i=0; i<size; i++)
  {
    fscanf(ptr,"%d",&array[i]);
  }
  free(ptr);
  return array;
}

der return soll in Funktion einer Funktion sort() dann sortiert werden.
Durch herausprobieren habe ich gemerkt, dass die obige Funktion mein 
Programm am terminieren hindert, ich verstehe aber nicht wieso.
LG Felix

von Theor (Gast)


Bewertung
0 lesenswert
nicht lesenswert
In dem anderen Thread sind Dir sinnvolle Antworten gegeben worden.
Beitrag "malloc() return Array (Programm terminiert nicht)"

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Gibt einlesen_size() denn das richtige zurück (Dateigröße / 
sizeof(int))?

Und:
Felix W. schrieb:
> free(ptr);

Eine Datei schließt man mit fclose(), nicht mit free().

von zitter_ned_aso (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Felix W. schrieb:
> der return soll in Funktion einer Funktion sort() dann sortiert werden.

Und wie soll die Funktion herausfinden wie groß dein Array ist? Die 
Arraygröße wird ja in deiner Funktion(oben) lokal ermittelt. (und 
zurückgegeben wird nur die Arrayadresse)

von imonbln (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Felix W. schrieb:
> /********************************
>    * Arraydefinition über malloc()*
>    *******************************/
>   array = (int *) malloc(size * sizeof(int));

Mein Prof. hätte zu den Kommentar gesagt, "Ich kann lesen!", ein 
Kommentar sollte sagen, warum man etwas macht und nicht was man macht.

Außerdem solltest du das malloc so schreiben:

 array = malloc( size * sizeof(*array)) 

Im C Standard wird dir garantiert das sich jeder Pointer nach (void *) 
und wieder zurück casten lassen kann, ohne Eigenschaften zu verlieren. 
Das heißt in diesen Fall, das der cast vom C Standard geschützt auch 
implizit gemacht werden kann. Zusammen mit den sizeof des 
dereferenzierten Array, sorgt der Code dafür das, wenn Array auf long 
geändert wird das nur in der Deklaration gemacht werden muss und nicht 
alle mallocs überprüft werden müssen.

Achtung, dass mit der implizieren cast geht nicht, wenn man einen C++ 
Compiler verwendet (aber dann sollte man besser C++ Code schreiben und 
kein malloc verwenden)

Felix W. schrieb:
> printf("Bitte Programm neustart.\n");
>     return 0;

Return 0, ist bei den meisten Programmen ein Erfolg, von daher ist der 
Return code verwirrend. Außerdem gibt dein Programm einen Pointer 
zurück, statt ein Integer und hier sind sich eigentlich alle einig, dass 
eine solche Funktion im Fehlerfall NULL zurückgeben sollte. Zwar ist
((void *) 0) 
 eine gültige Definition von NULL, du solltest aber dennoch besser NULL 
schreiben, um es den Leser einfacher zu machen, Sourcecode wird immer 
öfter gelesen als geschrieben, daher ergibt es Sinn auf das einfache 
Verstehen zu optimieren.

Felix W. schrieb:
> fscanf(ptr,"%d",&array[i]);

Denn return wert prüfen und eine gescheite Fehlerbehandlung einzubauen 
tut nicht hier nicht weh.

Felix W. schrieb:
> free(ptr);

Auch wenn das vielleicht suggeriert wird ist
FILE *ptr
 kein Filepointer, sondern ein Filehandle die Operation sollte also 
fclose sein und nicht free, btw ptr ist mir den wissen vielleicht ein 
suboptimaler Name.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
imonbln schrieb:
> Mein Prof. hätte zu den Kommentar gesagt, "Ich kann lesen!", ein
> Kommentar sollte sagen, warum man etwas macht und nicht was man macht.

Ja. Was man macht, sollte sich aus dem Code ergeben. Ein Kommentar, der 
nichts weiter ist als eine Prosa-Version einer Quelltextzeile, ist in 
der Regel nicht hilfreich.

> Außerdem solltest du das malloc so schreiben:
>
>  array = malloc( size * sizeof(*array))
> Im C Standard wird dir garantiert das sich jeder Pointer nach (void *)
> und wieder zurück casten lassen kann, ohne Eigenschaften zu verlieren.
> Das heißt in diesen Fall, das der cast vom C Standard geschützt auch
> implizit gemacht werden kann.

Das Wording ist nicht ganz präzise. Einen impliziten Cast gibt es nicht. 
Es handelt sich um eine implizite Konvertierung. Ein Cast ist das, was 
man hinschreibt, wenn man explizit eine Konvertierung auslösen will.

> Auch wenn das vielleicht suggeriert wird ist FILE *ptr kein Filepointer,
> sondern ein Filehandle die Operation sollte also fclose sein und nicht free,
> btw ptr ist mir den wissen vielleicht ein suboptimaler Name.

Ein Pointer ist es schon. Er zeigt aber nicht auf mit malloc() und 
Konsorten angeforderten Speicher, daher darf man darauf free() nicht 
anwenden.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.