tutorials.de Buch-Aktion 05/2012
ERLEDIGT
NEIN
ANTWORTEN
6
ZUGRIFFE
962
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    MPNuts MPNuts ist offline Mitglied Bronze
    Registriert seit
    Nov 2004
    Ort
    Oppenheim(zwischen MZ und WO)
    Beiträge
    48
    Hi,

    wie ist das mit der free Funktion?

    In meinem Programm sind alle Arrays über die malloc Funktion erstellt. Jetzt habe ich gelesen, ich soll danach, wieder den Befehl free benutzen.

    Die Arrays sollen wärend des gesamten Programmlaufs vorhanden sein.
    Jetzt ist meine Frage, wo muss ich dann den Befehl ansetzen. In der Funktion die auch die malloc Funktion aufruft:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    char * getarray (int index)
    {
    char * p;       //Pointer zur aufnahme des Arrays
    p=(char*)malloc(index*sizeof(char)); //Das System wird nach Speicher gefragt
    if (p==NULL)     //Frage nach dem "NULL-Zeiger"
    {
    printf("Zu wenig Speicherplatz vorhanden");
    }
    return p;       //Rückgabe des Pointers mit dem Array
    free(p);
    }

    Ist so das Array in der Funktion die das Array erhält dann noch da?

    Oder soll ich das Array erst zum Schluss des Programms wieder löschen? Oder muss ich nach jeder Übergabe wenn die Funktion abgeschlossen ist das Array löschen?

    Ich versteh das nicht so richtig.

    Vorallem, wenn ich eines meiner Arrays erst zu Programm ende wieder löschen will stürzt mein Programm ab.
     

  2. #2
    Vaethischist Tutorials.de Gastzugang
    Der Aufruf von free(p) ist "unreachable code", will sagen: der Code wird nie ausgeführt. Freigeben mußt Du den Speicher dann, wenn das Array nicht mehr gebraucht wird. Also in Deinem Fall, wenn das Array immer vorhanden sein muß, wenn das Programm beendet wird. Der Programmabsturz hat vermutlich andere Ursachen, aber die kann man bei dem kurzen Stück Code freilich nicht erkennen...
     

  3. #3
    MPNuts MPNuts ist offline Mitglied Bronze
    Registriert seit
    Nov 2004
    Ort
    Oppenheim(zwischen MZ und WO)
    Beiträge
    48
    Danke,

    noch eine Frage, ist nicht ganz rübergekommen, ist es egal, in welcher Funktion ich die Arrays wieder aufhebe, oder muss ich sie mit dem Pointer wieder löschen mit dem ich sie auch erstellt habe.

    Wenn ja, gäbe es ein Problem, da die Pointer ja nicht mehr existieren, da sie von einer Unterfunktion erstellt werden.

    Warum kann ich das folgende Array nicht aufheben, es wir in einer der zwei Funktionen beschrieben, erstellt wird es in der Funktion oben.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    
    char * indize (char * ar1, char * ar2, int a1 ,int a2)
    {
    [b]char * arziel;[/b]
    int index, z;
    index=a1+a2; //Errechnen der Größe des Ziel-Arrays
    [b]arziel=getarray(index); //Aufruf(getarray), Ziel-Array wird erstellt[/b]
    z=0;
    for (int i=0; i < index; i++)
    {
    if (a1>=0) //Bis Array zuende
    {
    [b]arziel[z]=ar1[a1];[/b]
    z++;a1--;
    } //Schreiben von Quell in Ziel-Array
     
    if (a2>=0) //Bis Array zuende
    {
    [b]arziel[z]=ar2[a2];[/b]
    z++;a2--;
    } //Schreiben von Quell in Ziel-Array
    }
    [b]return arziel;[/b]
    }
    //////////////////////////////////////////////////////////////////////////////////////////////
    ///////// indize
    //////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////////////////////////////////////////////////////////////////////////////////
    ///////// deref
    //////////////////////////////////////////////////////////////////////////////////////////////
    char * deref (char * ar1, char * ar2, int a1 ,int a2)
    {
    [b]char * arziel;[/b]
    int index, z;
    index=a1+a2; //Errechnen der Größe des Ziel-Arrays
    [b]arziel=getarray(index); //Aufruf(getarray), Ziel-Array wird erstellt[/b]
    z=0;
    for (int i=0; i < index; i++)
    {
    if (a1>=0) //Bis Array zuende
    {
    [b]*(arziel+z)=*(ar1+a1);[/b]
    z++;a1--;
    } //Schreiben von Quell in Ziel-Array
    if (a2>=0) //Bis Array zuende
    {
    [b]*(arziel+z)=*(ar2+a2);[/b]
    z++;a2--;
    } //Schreiben von Quell in Ziel-Array
    }
    [b]return arziel;[/b]
    }
    //////////////////////////////////////////////////////////////////////////////////////////////
    ///////// deref
    //////////////////////////////////////////////////////////////////////////////////////////////

    Was passiert wenn ich das Array einfach nicht wieder lösche?
    Geändert von MPNuts (22.11.04 um 08:59 Uhr)
     

  4. #4
    Registriert seit
    Oct 2003
    Beiträge
    1.706
    noch eine Frage, ist nicht ganz rübergekommen, ist es egal, in welcher Funktion ich die Arrays wieder aufhebe, oder muss ich sie mit dem Pointer wieder löschen mit dem ich sie auch erstellt habe.
    Das geht ohne Probleme, vorrausgetzt du gibst den Zeiger des erstellten Speichers
    dem Aufrufer der Funktion auch wieder zurück,
    somit besitzt deine aufrufende Funktion den Zeiger auf den in der aufgerufenen
    Funktion besorgten Speicher und du kannst diesen ohne Probleme wieder mittels
    delete oder free freigeben...

    Was passiert wenn ich das Array einfach nicht wieder lösche?
    Dann hast du ein Speicherleck, wenn dir die Referenz ( der Zeiger) auf den von
    dir allokierten Speicher einmal verloren geht, hast du keine Möglickeit
    diesen irgendwann wieder freizugeben, und somit verschwendest du den Speicher.

    Warum kann ich das folgende Array nicht aufheben, es wir in einer der zwei Funktionen beschrieben, erstellt wird es in der Funktion oben.
    Aus deinem Code ist für mich nicht ersichtlich wo du dieses tust...

    Gruß

    RedWing
     
    "I'm not deaf, I'm ignoring you"
    ----

  5. #5
    MPNuts MPNuts ist offline Mitglied Bronze
    Registriert seit
    Nov 2004
    Ort
    Oppenheim(zwischen MZ und WO)
    Beiträge
    48
    Erstmal Danke für deine Hilfe.

    Naja, das Problem ist, das Array wird wie gesagt, jetzt am ende wieder gelöscht, aber es wird in der Funktionshiraschie ganz unten erstellt aber erst wieder ganz oben gelöscht. dazwischen liegen 3 bis 4 Funktionen
    getarray(hier wird es erstellt)->einlesen(es wird beschrieben)->verein(hier wird das nicht zu löschende Array erstellt)->indize oder deref (das nicht zu löschende Array wird mit den anderen beschrieben)->zurück an verein(char* p; p=deref(Array1, Array2))->main(hier soll es am ende gelöscht werden.
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    
    char * verein ()
    {
    char * ar1; //Pointer auf das erste Array
    char * ar2; //Pointer auf das zweite Array
    [b]char * arziel; //Pointer auf das Ziel-Array[/b]
    char a; //Auswahl on Indizes oder Dereferentiert
    int i;  //Zählvariablen
    int a1, a2, index; //Größe der Arrays
    do
    {
    do
    {
    printf("\nBitte geben Sie die erste Zeichenfolge ein:\n\t");
    ar1=eingabe(); //Aufruf der eingabe Funktion, erstellen und beschreiben des Arrays
    a1=--globalindex; //Der Index wird aus der globalen Variable geschrieben
    printf("\nBitte geben Sie die zweite Zeichenfolge ein:\n\t");
    ar2=eingabe(); //Aufruf der eingabe Funktion, erstellen und beschreiben des Arrays
    a2=--globalindex; //Der Index wird aus der globalen Variable geschrieben
    index=a1+a2; //Errechnen der Größe des Ziel-Arrays
    printf("\n\nIst diese Eingabe korrekt?\nDuecken Sie 'j' um die Eingabe zu bestaetigen\n");
    a=getch();
    system("cls");
    }while (a!='j');
    a1--;
    a2--; //Formatieren der Zählwerte
    printf("\n\t1. Dereferenziert\n\t2. Indizes");
    a=getch();
    system("cls");
    if (a=='1') //Auswahl welche Sotierfunktion benutzt wird
    {
    [b]arziel=deref(ar1, ar2, a1, a2);[/b]
    }else   //Aufruf der Sotierfunktion mit Dereferenzierung
    {
    [b]arziel=indize(ar1, ar2, a1, a2);[/b]
    }    //aufruf der Sotierfunktion mit Indizes
    a1++;a2++;
    printf("\n\t1. Zeichenkette\t: ");
    for (i=0; i < a1; i++)//Ausgabe des ersten Arrays
    {
    printf("%c", ar1[i]);
    }
    printf("\n\t2. Zeichenkette\t: ");
    for (i=0; i < a2; i++)//Ausgabe des zweiten Arrays
    {
    printf("%c", ar2[i]);
    }
    printf("\n\n\tZiel-Array\t: ");
    for (i=0; i < index; i++)//Ausgabe des Zielarrays
    {
    printf("%c", arziel[i]);
    }
     
    globalindex=index; 
     
    free(ar1); //Speicherplatz wir wieder freigegeben
    free(ar2);
    printf("\n\nSind Sie mit dem Ergebnis unzufrieden?\n\tDann druecken Sie 'j', ");
    printf("jede andere Taste um fortzufahren.");
    a=getch();
    system("cls");
    }while (a!='j');
    [b]return arziel;[/b]
    }
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    
    //////////////////////////////////////////////////////////////////////////////////////////////
    ///////// main
    //////////////////////////////////////////////////////////////////////////////////////////////
    void main ()
    {
    [b]char * p;[/b]
    int prend, index;
    char a;
     
    do
    {
    system("cls");
    printf("\n\t\t\tMenue\n\n\t\tStart \t\t[s]\n\t\tVeraendern \t[v]\n\t\tAbout \t\t[a]");
    printf("\n\t\tBeenden \t[b]");
    a=getch();
    system("cls");
    switch (a)
    {
    case('s'):{ //Aufruf von f(verein)
    [b]p=verein();[/b]
    index=globalindex;
    prend=1;
    break;}
    case('v'):{ //Aufruf von f(veraender)
    veraender(p, index);
    prend=1;
    break;}
    case('b'):{ //Abbruchbedingung der Schleife
    prend=-1;
    printf("\n\n\t\t");
    break;}
    case('a'):{ //Aufruf der Programmbeschreibung
    about();
    prend=1;
    break;}
    default:{ //Wiederholung der Schleife
    prend=1;}
    }
    } while (prend>0);
    [b]free(arziel);[/b]
    }

    Naja, so sieht das Programm aus, schon mal danke, wenn sich einer die Mühe macht das durchzusehen, auch der Quellcode in meinem letztzen Post gehören dazu. Alle Fett gedruckten dinge bezeihen sich auf das bestimmte Array
    Geändert von MPNuts (22.11.04 um 08:57 Uhr)
     

  6. #6
    Registriert seit
    Oct 2003
    Beiträge
    1.706
    Code :
    1
    2
    3
    
    while (prend>0);
    free(arziel);
    }
    Hi,
    also ich hoff mal ich hab deinen Code jetzt richtig entziffert,

    1.) Das while kannst du dir sparen, da der Speicher eh nur im ersten case Label allokalisiert
    wird...
    So würde es leserlicher ausschauen:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    char *p = NULL;
    switch(...){
      case 's': Speicher allokalisieren; break;
      ...
    }
    ...
    if(p != NULL)
       free(p);

    2.) Wie man am obigen Codeschnipsel sieht musst du p freigeben und nicht arziel, arziel ist
    in deiner main Funktion gar nicht deklariert sondern nur in deinen anderen Funktionen
    bekannt und die geben ja den Pointer arziel an p im main zurück, somit zeigt p auf den
    Speicher der irgendwo in deinen Funktionen allokalisiert wurde.

    Gruß

    RedWing
     
    "I'm not deaf, I'm ignoring you"
    ----

  7. #7
    MPNuts MPNuts ist offline Mitglied Bronze
    Registriert seit
    Nov 2004
    Ort
    Oppenheim(zwischen MZ und WO)
    Beiträge
    48
    Danke für die Mühe, war bestimmt nicht sehr spassig!

    Zitat Zitat von RedWing
    Hi,
    also ich hoff mal ich hab deinen Code jetzt richtig entziffert,

    1.) Das while kannst du dir sparen, da der Speicher eh nur im ersten case Label allokalisiert
    wird...
    So würde es leserlicher ausschauen:
    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    char *p = NULL;
    switch(...){
    case 's': Speicher allokalisieren; break;
    ...
    }
    ...
    if(p != NULL)
    free(p);

    RedWing
    Das while gehört zum do->while, ist, dass das Programm immer wieder von vorne beginnt.

    Mit deinem Beispiel klappt es leider auch nicht in meinem Programm, aber ich habe heute in der FH erfahren, dass ein anderer das selbe Problem hat. Kann es sein, dass man so wie die Arrays erstellt wurden sie nicht mehr löschen kann? Aber was dagegen spricht, zwei der drei Arrays lassen sich problemlos wieder löschen, nur das indem die Daten der beiden anderen gespeichert werden nicht.
    Kann ich eigentlich auch p=NULL schreiben? Ginge das?

    Sollte ich Pointer immer mit einem Wert füllen, wie wenn es noch nicht feststeht mit =NULL?

    Zitat Zitat von RedWing
    2.) Wie man am obigen Codeschnipsel sieht musst du p freigeben und nicht arziel, arziel ist
    in deiner main Funktion gar nicht deklariert sondern nur in deinen anderen Funktionen
    bekannt und die geben ja den Pointer arziel an p im main zurück, somit zeigt p auf den
    Speicher der irgendwo in deinen Funktionen allokalisiert wurde.
    RedWing
    Ich hatte das noch schnell nur im Post eingefügt, da es ja nicht funktionierte, habe ich es aus meinem Programm schon entfernt gehabt, und mich dann natürlich gleich in der Variablen vergriffen. SORRY!
     

Ähnliche Themen

  1. malloc problem
    Von Manda im Forum C/C++
    Antworten: 44
    Letzter Beitrag: 25.04.09, 17:21
  2. C# und malloc
    Von amigian im Forum .NET Datenverwaltung
    Antworten: 0
    Letzter Beitrag: 08.02.08, 11:25
  3. Antworten: 6
    Letzter Beitrag: 15.06.04, 15:08
  4. malloc/free .. führt zu Absturz
    Von Sebastian L im Forum C/C++
    Antworten: 3
    Letzter Beitrag: 19.11.03, 19:09
  5. Bilder 4 Free und Fonts 4 Free
    Von Atomisierer im Forum Photoshop
    Antworten: 3
    Letzter Beitrag: 01.01.02, 17:53