2016-04-02 11 views
1

私は素数を見つけるプログラムを書いて、realloc()を使って '* primes'ブロックのサイズを変更します。私が6より大きいビット数を置くと、最初の2つの値は未定義の振る舞いのように見え、私の人生にとってなぜこのようなことが起こるのか理解できません。 pls halp。Cプライムジェネレータ(プログラム投稿、実行可能ファイル)にreallocで見かけ上定義されていない動作

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

typedef int int64_t; 

void *safe_calloc(size_t,size_t); 
void *safe_realloc(void*,size_t); 

int main() 
{ 
    printf("Prime Generator\nPlease enter the number of usable bits: "); 
    int bits =0, maxNum=1, size = 6, elems = 3; 

    scanf("%d",&bits); 

    if(bits<1) 
     exit(0); 

    int i=0; 
    for(; i < bits; i++) 
     maxNum*=2; 

    int *primes = safe_calloc(size*sizeof(int),sizeof(int)); 
    int *temp = safe_calloc(size*sizeof(int),sizeof(int)); 

    primes[0] = 1; 
    primes[1] = 2; 
    primes[2] = 3; 

    int n = 3,j; 
    for(; n < maxNum; n+=2){ 

     for(j = 2; j < elems; j++){ 

      if(n%primes[j] == 0) 
       break; 
      else if(j == elems-1){ 

      primes[elems++] = n; 
      if((size-elems) < 2){ 

       for(i = 0; i < elems; i++) 
        printf("%d\n",primes[i]); 
       printf("\n"); 

       size += 8; // add 8 spaces to the prime storage array 
       temp = safe_realloc(primes,size*sizeof(int)); 

       for(i = 0; i < elems; i++) 
        printf("%d\n",primes[i]); 
       printf("\n"); 

       memmove(temp,primes,(size-8)*sizeof(int)); // copy over data to new array, just to be sure 
       primes = temp; 

       for(i = 0; i < elems; i++) 
        printf("%d\n",primes[i]); 
       printf("\n"); 
       } 
      } 
     } 
    } 
    if(bits == 1){ 
     printf("1"); 
    } 
    else{ 
     for(i = 0; i < elems; i++) 
      printf("%d\n",primes[i]); 
     printf("\n"); 
    } 
    free(temp); 
    free(primes); 

    return 0; 
} 
void *safe_calloc(size_t length,size_t dataSize){ 
    int *tmp; 
    if ((tmp = calloc(length,dataSize)) == NULL) { 
     printf("ERROR: calloc failed"); 
     exit(0); 
    } 
    return tmp; 
} 
void *safe_realloc(void* ptr, size_t arraySize){ 
    int *tmp; 
    if ((tmp = realloc(ptr,arraySize)) == NULL) { 
     printf("ERROR: realloc failed"); 
     exit(0); 
    } 
    return tmp; 
} 
+0

注意:一般的に「報告するために使用される '0'の 'exit'コードエラーはありません( 'main'が暗黙的に返すものです)。代わりに小さな正の整数を返す必要があります。他の値が使用されていない場合は、通常は「1」です。 – Olaf

+0

1)エラーではありません: 'int * primes = safe_calloc(size * sizeof(int)、sizeof(int));'おそらく少し大きすぎます... 2: 'primes [0] = 1;' 'これは良い考えだと思いません。 – wildplasser

答えて

1

呼び出し後にreallocに入れたポインタは使用しないでください。返されたポインタのみを使用してください。またmemmove /コピーする必要はありません。他の人はあなたがある方法でMEMMOVEを使用して、指摘したように

The contents of the object shall remain unchanged up to the lesser of the new and old sizes. If the new size of the memory object would require movement of the object, the space for the previous instantiation of the object is freed.

1

データをmemmoveにする必要はありません。 reallocはそれを自動的に行い、古いバッファを解放します。したがって、memmoveは無効な(すでに解放されている)メモリ空間からコピーしています。

0

が正しくありません。 reallocは現在の内容を保存し、追加のメモリを追加するので、必要に応じてstrcatまたはstrcpyを続けることができます。その後、元に再割り当て、NULLをチェックし、一時的BUFを使用し、記憶喪失を防止するためにrealloc()

...

temp = realloc(temp, 20); 
if(!temp) 
{ 
    //handle error and exit 
} 
buf = temp;//transfer successfully allocated memory 
.... 
//use newly reallocated buf 
+0

@ user3386109 - 私はそれらを読んでいました。ヌルをチェックしていますが、あなたは正しい方法で 'realloc()'を使っていません。 'memmove()'は必要ありません。 'realloc()'のこの機能について言及することで、割り当て関数の戻り値を一般的にチェックすることはそれほど重要ではないことを伝えたくありませんでした。 _しかし、これはあなたが正しく行った!_ :)しかし、 'realloc()'と 'memmove()'と一緒に使ったメソッドは問題を引き起こします。 – ryyker

関連する問題