2016-04-02 53 views
1

Asal sayıları bulmak için bir program yazdım ve '* primes' bloğunun boyutunu değiştirmek için realloc() kullanıyorum. 6'dan büyük herhangi bir sayıyı koyduğumda, ilk iki değerin tanımlanmamış davranışa benzediğini ve hayatımın neden böyle olduğunu anlayamadığımı görüyorum (takip eden sayılar doğrudur). pls halp.Görünüşte tanımlanmamış davranış, C prime generator'da realloc (program yayınlandı, çalıştırılabilir)

#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

Not: genellikle "rapor etmek için kullanılır 0'' Bir 'exit' kodu hata yok "(ayrıca" main "kelimesi de dolaylı olarak geri döner). Başka bir değer kullanılmıyorsa, genellikle küçük bir pozitif tam sayı döndürmelisiniz. – Olaf

+0

1) Hata değil: int * primes = safe_calloc (size * sizeof (int), sizeof (int)); 'büyük olasılıkla biraz fazla büyük ... 2: 'primes [0] = 1;' don Bunun iyi bir fikir olduğunu düşünmüyorum. – wildplasser

cevap

1

Aramadan sonra realloc içine koyduğunuz işaretçiyi kullanmayın - sadece döndürülen işaretçiyi kullanın. Ayrıca memmove/kopyalamak gerekmez: Başkaları sen yolla memmove'un kullanarak, işaret gibi

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

Verilere memmove gerek yoktur. realloc, eski arabelleği otomatik olarak yapar ve serbest bırakır. Bu nedenle memmove geçersiz (zaten boş olan) bir bellek alanından kopyalanıyor.

0

doğru değil. realloc, geçerli içeriği korur ve ek bellek ekler, böylece daha sonra strcat veya strcpy ile devam edebilirsiniz. Daha sonra orijinal Atanacak, NULL denetlemek, geçici buf kullanmak, hafıza kaybını önlemek için realloc() için

...

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

@ user3386109 - Onları okudum, ve null'u kontrol etseniz de, "realloc()" ı doğru şekilde kullanmıyorsunuz. memmove() 'gerekli değildir. Realloc() 'ın bu özelliğinden bahsederek, genel olarak tahsis fonksiyonlarının geri dönüşünü kontrol etmek için daha az önemli olduğunu iletmek istemedim. _But evet, bu doğru bir şekilde yaptınız! _ :) Ancak, memove() ile birlikte “realloc()” ile çalıştığınız yöntem problemlere neden olacaktır. – ryyker