2016-11-23 2 views
2

Ich versuche, den Speicher um eine Zeile in Double Char Zeiger zu erhöhen, aber aus irgendeinem Grund stürzt das Programm ab, obwohl ich keine Warnungen bekomme. Ich habe gegoogelt und die Leute bieten immer wieder diesen Weg an, aber es funktioniert nicht für mich. Weißt du, wo ist der Haken? Es ist in der letzten Zeile.Wie Realloc mit Double Char Zeiger in C verwenden?

Vielen Dank im Voraus!

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#define E 255 

void Palindromas(char* Zodis, char eilute[E], int *kiekis, char** Ats); 

int main() 
{ 
    char Eilute [E]; 
    int i, kiekis = -1; 
    char** Ats; 
    char* Zodis; 

    Zodis = malloc(E * sizeof(char)); 
    Ats = malloc(1 * sizeof(char*)); 

    // Failu aprasymas 

    FILE *Duomenys = fopen("Duomenys.txt", "r"); 
    FILE *Rezultatai = fopen("Rezultatai.txt","w"); 

    //-------------------------------- 

    if (Ats == NULL) 
    { 
     printf("Atmintis nebuvo paskirta"); 
     exit(0); 
    } 

    if (Zodis == NULL) 
    { 
     printf("Atmintis nebuvo paskirta"); 
     exit(0); 
    } 

    if (Duomenys == NULL) printf("Nurodyto duomenu failo nera \n"); 

    while(fgets(Eilute, sizeof(Eilute), Duomenys)) 
    { 
     Palindromas(Zodis, Eilute, &kiekis, Ats); 
    } 

    for (i = 0; i <= kiekis; i++) 
    { 
     fprintf(Rezultatai, "%s ", Ats[i]); 
    } 

    free(Ats); 
    free(Zodis); 
    fclose(Duomenys); 
    fclose(Rezultatai); 

    return 0; 
} 

void Palindromas(char* Zodis, char Eilute[E], int *kiekis, char** Ats) 
{ 
    int i, l, j, index, ilgis, eil; 

    for(i = 0; 1 == sscanf(Eilute + i, "%s%n", Zodis, &l); i = i + l) 
    { 

     *kiekis = *kiekis + 1; 
     index = 1; 
     ilgis = strlen(Zodis); 

     Ats[*kiekis] = malloc(ilgis * sizeof(char)); 

     for (j = 0; j < ilgis; j++) 
     { 
      if (Zodis[j] != Zodis[ilgis - j - 1]) 
       index = 0; 
     } 

     if (index == 1) strcpy(Ats[*kiekis], Zodis); 

     eil = *kiekis + 2; 
     Ats = realloc(Ats, eil * sizeof(char*)); 
    } 
} 
+1

Bevor Sie etwas anderes tun, sollten Sie suchen for * emulieren Pass durch Referenz in C *. Was glaubst du passiert mit "Ats" in der "Palindromas" -Funktion, wenn du es zugewiesen hast? Wie wirkt sich das auf die 'Ats'-Variable in der' main'-Funktion aus? Denken Sie darüber nach, was Sie mit 'kiekis' machen. –

+0

Darüber hinaus schreiben Sie in der allerersten Iteration der Schleife zu 'Ats [* kiekis]', das * außerhalb der Grenzen liegt *. –

+1

Zuletzt, weisen Sie die Zeigervariable, die Sie an 'realloc' übergeben, nicht erneut zu. Wenn 'realloc' fehlschlägt, wird' NULL' zurückgegeben und Sie verlieren den Zeiger. Und * immer * nach Fehlern suchen (z. B. 'malloc' oder' realloc', die 'NULL' zurückgeben). –

Antwort

0

Ich musste Google verwenden, um Ihren Code zu verstehen, vielleicht können Sie das nächste Mal für uns übersetzen.

Ich habe ein paar Beobachtungen:

  • if (Duomenys == NULL) nur eine Fehlermeldung aus, aber die Ausführung nicht zu stoppen. es sollte wie die vorherigen Validierungen sein (und besser, wenn ein Fehlercode zurückgegeben wird).
  • Ats[*kiekis] = malloc(ilgis * sizeof(char)); ist falsch, sollte es Ats[*kiekis] = malloc((ilgis+1) * sizeof(char)); sein, weil es Platz für Null-End-Char benötigt.
  • if (Zodis[j] != Zodis[ilgis - j - 1]) index = 0; ist in Ordnung, aber besser wäre if (Zodis[j] != Zodis[ilgis - j - 1]) { index = 0; break; }, weil auf diese Weise die Schleife bei der ersten anderen Char stoppen wird.
  • if (index == 1) strcpy(Ats[*kiekis], Zodis); muss if (index == 1) strcpy(Ats[*kiekis], Zodis);else --*kiekis sein oder Ihr Ats Array wird auch keine Palindrome-Wörter enthalten.
  • Und vergessen Sie nicht, bevor frei jedes Element Ihrer Ats Array zu befreien das Array selbst mit so etwas wie for(i=0; i<=kiekis; i++) free(Ats[i]);

Schließlich, um Ihre Frage zu beantworten, die Ats Array realloc tun gerade:

Ats = realloc(Ats, (*kiekis+1) * sizeof(char*)); 

würde ich Ihre Funktion wie folgt neu zu organisieren:

void Palindromas(char* Zodis, char Eilute[E], int *kiekis, char** Ats) 
{ 
    int i, l, j, index, ilgis; 
    for(i = 0; 1 == sscanf(Eilute + i, "%s%n", Zodis, &l); i = i + l) 
    { 
     index = 1; 
     ilgis = strlen(Zodis); 
     for (j = 0; j < ilgis; j++) 
     { 
      if (Zodis[j] != Zodis[ilgis - j - 1]) 
      { 
       index = 0; 
       break; 
      } 
     } 
     if (index == 1) 
     { 
      ++*kiekis; 
      Ats = (char **)realloc(Ats, (*kiekis+1) * sizeof(char*)); 
      Ats[*kiekis] = dup(Zodis); // dup == malloc+strcopy 
     } 
    } 
} 
+0

Vielen Dank für Ihre Hilfe und Empfehlungen! Ich schätze es sehr. :) Ich habe bereits alle Ihre Beobachtungen aus der Zeit behoben, die ich die Hauptfrage gepostet habe, aber beim erneuten Zuweisen von Speicher stürzt das Programm immer noch ab ... Ich habe genau die gleiche Art gegoogelt, wie ich es gerne benutze Sie sagen, aber das Programm stürzt nur ab, wenn es gestartet wird. :(Ich werde versuchen, damit zu spielen, vielleicht werde ich erfolgreich sein. Ats = realloc (Ats, (* kiekis + 1) * sizeof (char *)); – Tukkas

+0

Es ist 'Ats = Realloc (Ats, (* kiekis + 1) * sizeof (char)); '*' * kiekis + 1' und nicht 'kiekis + 1' * – WPomier