2016-11-14 20 views
0

コンマで区切られた整数値を配列に読み込んで並列構造で処理しようとするプログラムを記述しました。 これにより、ダイナミック配列の最大サイズが固定されていることがわかりました。ダイナミックアレイのサイズは、通常、サイズを2倍にして動的に割り当てられます。それでも、5000を超える値を持つデータセットの場合、それを二重にすることはできません。動的配列に大きなスペースを割り当てる

技術的に、他の投稿が私たちにすべきことを指摘していたので、私はちょっと混乱しました(reallocを使用してください。代わりにスタックを使用しないでください)。

5000以下の値を持つファイルであれば問題ありません。 また、reallocを使っても同じ結果が得られました。

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 

// compile with gcc filename -lpthread -lm -Wall -Wextra -o test 

int reader(int ** array, char * name) { 
    FILE *fp; 
    int data,row,col,count,inc; 
    int capacity=10; 
    char ch; 
    fp=fopen(name,"r"); 
    row=col=count=0; 
    while(EOF!=(inc=fscanf(fp,"%d%c", &data, &ch)) && inc == 2){ 
     if(capacity==count) 
      // this is the alternative with realloc we tried. Still the same issue. 
      //*array=malloc(sizeof(int)*(capacity*=2)); 
      *array = realloc(*array, sizeof(int)*(capacity*=2)); 

     (*array)[count++] = data; 
     //printf("%d ", data); 
     if(ch == '\n'){ 
      break; 
     } else if(ch != ','){ 
      fprintf(stderr, "format error of different separator(%c) of Row at %d \n", ch, row); 
      break; 
     } 
    } 
    // close file stream 
    fclose(fp); 
    //*array=malloc(sizeof(int)*count); 
    *array = realloc(*array, sizeof(int)*count); 
    return count; 

} 

int main(){ 


    int cores = 8; 
    pthread_t p[cores]; 
    int *array; 
    int i = 0; 
    array=malloc(sizeof(int)*10); 
    // read the file 

    int length = reader(&array, "data_2.txt"); 
    // clean up and exit 
    free(array); 
    return 0; 
} 

EDIT:私たちが試したreallocコマンドを含めて、元のテスト値(10で始まる)に値を戻しました。しかし、これは結果に影響を与えませんでした、またはむしろまだ動作しません。とにかくエラーを指摘してくれてありがとう!私はまた、含まれるコードを関連する部分に減らしました。

がこのように動作するはずですが、私たちが見落とした小さな間違いかもしれません。 ありがとうございます。

+5

私は 'realloc'を見ていません。私はあなたが' malloc'を使って繰り返してメモリを漏らしているのを見ています。 –

+0

1)あなたはどのように知っていますか?私はあなたがすべき 'malloc'の結果を確認することはありません。 2) 'while'ループに大量のメモリリークがあります。 – Olaf

+0

あなたの配列は、最初は10個の要素配列として割り当てられますが、50001個の要素で満たされます。そのため、あなたはあなたのmemeoryを台無しにしています。 reallocを使うか、配列を手作業でコピーして古いものを解放してください。それに加えて、私はいくつかのコーディングスタイルガイドを読むことをお勧めします。あなたのコードは実際にはいくつかの場所で醜いです。さらに、問題の最小限の実例を作成する必要があります。多くのコードはあなたの問題に属しません。 @EugeneSh。 –

答えて

1

質問後の新しい答えはreallocの使用が間違っている

を更新されています。新しいポインタに常にreallocを置き、古いポインタを上書きする前にNULLをチェックします。

同様:

int* tmp = realloc(....); 
if (!tmp) 
{ 
    // No more memory 
    // do error handling 
    .... 
} 
*array = tmp; 

オリジナルの答え(完全には有効ではありません質問が更新された後)

あなたは、現在のコードといくつかの深刻な問題を抱えています。 main

あなたが持っている:

array=malloc(sizeof(int)*10); // This only allocates memory for 10 int 

int length = reader(&array, "data_1.txt"); 

readerにあなたが持っている:

int capacity=5001; 

をですから、アレイ容量は、あなただけで開始する10のためのメモリを予約していても5001であることを前提としています。したがって、予約された配列の外側に書くことになります(つまり、未定義の動作)。

もっと良いアプローチは、関数内のすべての割り当てを処理することです(つまり、mainには割り当てを行わない)ことができます。それを行う場合は、capacity0に初期化し、容量の増加方法を書き換えます。

さらに、readerであなたが持っている:あなたが、アレイ内に既にすべてのデータを失うようmallocを使用し、同様にメモリリークが発生することが間違っている

if(capacity==count) 
     *array=malloc(sizeof(int)*(capacity*=2)); 

。代わりにreallocを使用してください。

は最後に、あなたが持っている:

*array=malloc(sizeof(int)*count); 

をこれも上記と同じ理由で間違っています。正確なサイズ(別名カウント)を使用する場合は、realloc

+0

のコードで動作するはずです。コードをお詫び申し上げます。私は急いでアップロードしようとしましたが、これは大きな間違いでした。縮減されたコードは現在入手可能です。急に変更された値であなたを邪魔するのではなく、私の元の問題を指摘する必要があります。 – dennlinger

+0

@dennlinger - '* array = realloc ... 'を使わないでください。失敗した場合、以前のデータを失ってしまいます。 'realloc'を正しく使用するために投稿したリンクを確認してください。 – 4386427

+0

@dennlinger - 値が5000を超えるとプログラムはどのように失敗しますか? – 4386427

関連する問題