在C prime生成器中使用realloc看似未定义的行为(程序已发布,可运行)

时间:2016-04-02 20:13:10

标签: c primes realloc

我写了一个程序来查找素数,我使用realloc()来改变' *素数的大小。块。当我把任意数量的位大于6时,我发现前两个值看起来像未定义的行为,我不能在我的生活中理解为什么会发生这种情况(后面的数字都是正确的)。请停下来。

#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;
}

3 个答案:

答案 0 :(得分:1)

您不需要memmove数据。 realloc自动执行此操作并释放旧缓冲区。所以memmove正在从无效(已经释放的)内存空间进行复制。

答案 1 :(得分:1)

请勿在调用后使用放入realloc的指针 - 仅使用返回的指针。您也无需复制/ memmove

  

对象的内容应保持不变,直至较小   新旧尺寸。如果内存对象的新大小会   需要移动物体,前者的空间   释放对象的实例化。

答案 2 :(得分:0)

正如其他人所指出的那样,以你的方式使用memmove是不正确的。 realloc 保留当前内容,并添加额外内存,以便您可以根据需要继续使用strcat或strcpy。

对于 class Post: PFObject, PFSubclassing { // Your Properties @NSManaged var owner: PFUser @NSManaged var likeCount: NSNumber static func parseClassName() -> String { return "Post" // Your Class Name } } 防止内存丢失,请使用临时buf,检查是否为NULL,然后重新分配给原始...

realloc()