2016-12-11 24 views
1

*arr = malloc(i * sizeof(struct cluster_t*));を実行すると、コードがクラッシュすることがあります。クラスタは構造体です。 問題は何か分かりません。ここmalloc実行時にプログラムがクラッシュする

count=20 
40 86 663 
43 747 938 
47 285 973 
49 548 422 
52 741 541 
56 44 854 
57 795 59 
61 267 375 
62 85 874 
66 125 211 
68 80 770 
72 277 272 
74 222 444 
75 28 603 
79 926 463 
83 603 68 
86 238 650 
87 149 304 
89 749 190 
93 944 835 

である:第二の入力は、別々の構造としては、配列にTXTファイルをロードすることになっている構造体(クラスタ)のアレイ、各ラインである第一の入力はこれを含む.txtファイルであります - 私が最新に保つ

int load_clusters(char *filename, struct cluster_t **arr) //nefunkcne 
{ 
    assert(arr != NULL); 

    char buffer_load[256] = {'0'}; 
    int riadok = 0; 
    int count = 0; 

    int *X = malloc(sizeof(int)); 
    if (X == NULL) { 
     perror("Chyba mallocu na load_clusters X"); 
     free(X); 
     exit(EXIT_FAILURE); 
    } 

    int *Y = malloc(sizeof(int)); 
    if (Y == NULL) { 
     perror("Chyba mallocu load_clusters Y"); 
     free(X); 
     free(Y); 
     exit(EXIT_FAILURE); 
    } 

    int *ID = malloc(sizeof(int)); 
    if (ID == NULL) { 
     perror("Chyba mallocu v load_clusters ID"); 
     free(X); 
     free(Y); 
     free(ID); 
     exit(EXIT_FAILURE); 
    } 

    FILE *subor = fopen(filename, "r"); 
    if (subor == NULL) { 
     perror("Chyba nacitania suobru fopen load_clusters!"); 
    } 

    while (fgets(buffer_load, sizeof buffer_load, subor) != NULL) { 
     if (riadok > 0) { 
      struct cluster_t shluk; 
      sscanf(buffer_load,"%d %d %d", ID, X, Y); 
      init_cluster(&shluk, 1); 
      struct obj_t objekt; 
      objekt.id = *ID; 
      objekt.x = *X; 
      objekt.y = *Y; 

      append_cluster(&shluk, objekt); 

      arr[riadok - 1] = malloc(sizeof(struct cluster_t*)); 
      if (arr[riadok-1] == NULL) { 
       perror("Chyba mallocu v load_clusters 388!"); 
       free(arr[riadok - 1]); 
       exit(EXIT_FAILURE); 
      } 

      (*arr)[riadok - 1] = shluk; 
     } else { 
      sscanf(buffer_load, "count=%d", &count); 
      *arr = malloc(count * sizeof(struct cluster_t)); 
      if (arr == NULL) { 
       perror("Chyba mallocu v load_clusters 400!"); 
       free(*arr); 
       exit(EXIT_FAILURE); 
      } 
     } 
     riadok++; 
    } 

    fclose(subor); 
    free(X); 
    free(Y); 
    free(ID); 
    return cout; 
} 

全コード( `-std = c99をを使用することを忘れないでください:障害があるように思われるコードの一部は、(私は少し最初に答えた後、それを修正)これは完全なコードではありませんWextra -Wall -Werror -DNDEBUGまた数学ライブラリのためgcc内にある場合は-lm):

+0

コメント拡張議論のためではありません。この会話は[チャットに移動]されています(http://chat.stackoverflow.com/rooms/130349/discussion-on-question-by-luk164-program-crashes-when-malloc-executed)。 –

+0

上記の構造のdefを表示するのに常に良い –

答えて

0

次のコードはきちんとコンパイルされますが、サブ関数がないためリンクされません。

警告:コードをテストすることができないため、正しく動作することを100%保証していません。

#include <stdio.h> // fopen(), fclose(), fgets() 
#include <stdlib.h> // exit(), EXIT_FAILURE, malloc() 
#include <assert.h> // assert() 
#include <string.h> // strchr() 

struct cluster_t 
{ 
}; 

struct obj_t 
{ 
    int id; 
    int x; 
    int y; 
}; 

void init_cluster(struct cluster_t*, int); 
void append_cluster(struct cluster_t*, struct obj_t*); 

int load_clusters(char *filename, struct cluster_t **arr) //nefunkcne 
{ 
    assert(arr != NULL); 

    char buffer_load[256] = {'0'}; 
    int riadok = 0; 
    int i = 0; 

    int X; 
    int Y; 
    int ID; 

    FILE *subor = NULL; 
    if(NULL == (subor = fopen(filename, "r"))) 
    { 
     perror("Chyba nacitania suobru fopen load_clusters!"); 
     exit(EXIT_FAILURE); 
    } 

    // implied else, fopen successful 

    // initialize for number of struct instances 
    if(! fgets(buffer_load, sizeof(buffer_load), subor)) 
    { 
     fprintf(stderr, "unable to read first line from input file\n"); 
     exit(EXIT_FAILURE); 
    } 

    char *token = NULL; 
    if(NULL == (token = strchr(buffer_load, '='))) 
    { 
     fclose(subor); 
     exit(EXIT_FAILURE); 
    } 

    else 
    { // else delimeter found 
     token++; // step past '=' 
     i = atoi(token); 

     // allocate array of pointers to 'struct cluster_t' 
     if(NULL == (*arr = malloc((size_t)i * sizeof(struct cluster_t*)))) 
     { 
      perror("Chyba mallocu v load_clusters 400!"); 
      fclose(subor); 
      exit(EXIT_FAILURE); 
     } 

     // implied else, malloc successful 
    } 


    while(riadok < i && fgets(buffer_load, sizeof buffer_load, subor)) 
    { 
     struct cluster_t shluk; 
     sscanf(buffer_load,"%d %d %d", &ID, &X, &Y); 

     init_cluster(&shluk, 1); 

     struct obj_t objekt; 
     objekt.id = ID; 
     objekt.x = X; 
     objekt.y = Y; 
     append_cluster(&shluk, &objekt); 

     if(NULL == (arr[riadok] = malloc(sizeof(struct cluster_t)))) 
     { 
      perror("Chyba mallocu v load_clusters 388!"); 
      fclose(subor); 

      for(int j=0; j<riadok; j++) 
      { 
       free(arr[j]); 
      } 

      exit(EXIT_FAILURE); 
     } 

     memcpy(arr[riadok], &shluk, sizeof(struct cluster_t)); 

     riadok++; 
    } 

    fclose(subor); 

    return i; 
} 
+0

gccの完全なコードとカスタム設定を投稿しました。 – Luk164

0

あなたのコードは、あまりにも複雑であり、問​​題がある:

  • あなただけのローカル変数のアドレスを渡し、scanf()へのポインタを渡すためにデータを割り当てる必要はありません。
  • 戻り値scanf()を確認してください:成功したコンバージョン数を返します。変換が失敗した場合、対応する変数は設定されず、残りの変換も失敗します。
  • count=20などの空白で始まるtxtファイルの場合、scanf形式には、これらのスペースを消費するための初期領域が含まれている必要があります。" count=%d"
  • ポインタと構造体の間には多くの混乱があります:関数がクラスターの配列を割り当てるか、またはオブジェクトのシーケンスを割り当てられたクラスターにロードする必要がありますか?ここ

単一割り当てられたクラスタにオブジェクトをロードする簡易版である:

int load_clusters(const char *filename, struct cluster_t **arr) { 
    char buffer_load[256]; 
    int riadok, count, X, Y, ID; 
    struct cluster_t *cp; 

    assert(arr != NULL); 

    // Open the input file 
    FILE *subor = fopen(filename, "r"); 
    if (subor == NULL) { 
     perror("Chyba nacitania suobru fopen load_clusters!"); 
     exit(EXIT_FAILURE); 
    } 

    // Read and parse the count line 
    if (fgets(buffer_load, sizeof buffer_load, subor) == NULL || 
     sscanf(buffer_load, " count=%d", &count) != 1) { 
     perror("missing count line in file\n"); 
     fclose(subor); 
     exit(EXIT_FAILURE); 
    } 

    // allocate and initialize the cluster 
    *arr = cp = malloc(sizeof(**arr)); 
    if (cp == NULL) { 
     perror("Chyba mallocu v load_clusters 400!"); 
     exit(EXIT_FAILURE); 
    } 
    init_cluster(cp, count); 

    riadok = 0; 
    while (riadok < count && 
      fgets(buffer_load, sizeof buffer_load, subor) != NULL) { 
     if (sscanf(buffer_load,"%d %d %d", &ID, &X, &Y) == 3) { 
      struct obj_t objekt; 
      objekt.id = ID; 
      objekt.x = X; 
      objekt.y = Y; 
      append_cluster(cp, objekt); 
      riadok++; 
     } 
    } 

    fclose(subor); 
    return riadok; 
} 
関連する問題