2016-11-23 15 views
2

私は二重のcharポインタで1行だけメモリを増やそうとしていますが、何らかの理由でプログラムがクラッシュします。私はgoogledと人々reallocにこの方法を提供し続けますが、それは私のために動作しません。あなたはキャッチがどこにあるか知っていますか?最後の行にあります。Cでdouble charポインタを使ったreallocの使い方は?

ありがとうございます!

#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

C *で参照渡しをエミュレートする*。あなたがそれを割り当てるとき、パインドロマス機能の 'Ats'はどうなると思いますか?それは 'main'関数の' Ats'変数にどのように影響しますか? 'キエキス 'で何をしているのか考えてみてください。 –

+0

さらに、ループの最初の反復で* out of bounds *である 'Ats [* kiekis]'に書き込んでいます。 –

+1

最後に、 'realloc'に渡すポインタ変数に再割り当てしないでください。 'realloc'が失敗すると' NULL'を返し、ポインタを失います。 *常に*エラーをチェックする( 'malloc'や' realloc'が 'NULL'を返すなど)。 –

答えて

0

あなたのコードを理解するためにgoogleを使用する必要がありました。次回は翻訳することができます。

私はいくつかの観測いる:

  • if (Duomenys == NULL)だけでエラーメッセージを出力しますが、実行を停止しません。前の検証と同じでなければなりません(エラーコードを返した方が良いでしょう)。
  • Ats[*kiekis] = malloc(ilgis * sizeof(char));が間違っています。ヌル終了文字の余地が必要であるため、Ats[*kiekis] = malloc((ilgis+1) * sizeof(char));である必要があります。
  • if (Zodis[j] != Zodis[ilgis - j - 1]) index = 0;でもいいですが、この方法でループが最初の異なるcharで停止するため、if (Zodis[j] != Zodis[ilgis - j - 1]) { index = 0; break; }が良いでしょう。
  • if (index == 1) strcpy(Ats[*kiekis], Zodis);は、if (index == 1) strcpy(Ats[*kiekis], Zodis);else --*kiekisでなければなりません。そうしないと、Ats配列には回文文字も含まれません。
  • そして、ちょうど行うAts配列のreallocし、あなたの質問に答える、for(i=0; i<=kiekis; i++) free(Ats[i]);最後

ようなもので自由に前に配列自体をあなたのAts配列の各要素を解放することを忘れないでください:

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

私はこのようなあなたの機能を再編成します:あなたが何かを行う前に、あなたが検索する必要があり、

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

ご協力いただきありがとうございます!ほんとうにありがとう。 :) 私は主な質問を投稿した時からあなたの意見をすべて修正しましたが、メモリを再割り当てするとプログラムはまだクラッシュします...私はそれを好きなように使うあなたが言っているが、プログラムは起動時にクラッシュする。 Ats = realloc(Ats、(* kiekis + 1)* sizeof(char *)); – Tukkas

+0

これは、Ats = realloc(Ats、 kiekis + 1)* sizeof(char)); '*' * kiekis + 1'ではなく 'kiekis + 1' * – WPomier

関連する問題