首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C素数生成器中带有realloc的看似未定义的行为(程序发布,可运行)

C素数生成器中带有realloc的看似未定义的行为(程序发布,可运行)
EN

Stack Overflow用户
提问于 2016-04-02 20:13:10
回答 3查看 56关注 0票数 1

我编写了一个查找素数的程序,并使用realloc()来更改'*primes‘块的大小。当我放置大于6的位数时,我发现前两个值似乎是未定义的行为,我无法理解为什么会发生这种情况(下面的数字都是正确的)。请停一下。

代码语言:javascript
复制
#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;
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-04-02 20:26:29

不要使用您在调用后放入realloc的指针,只使用返回的指针。您也不需要复制/memmove

对象的内容应保持不变,不超过较小的新的和旧的大小。如果内存对象的新大小需要对象的移动,则释放对象先前实例化的空间。

票数 1
EN

Stack Overflow用户

发布于 2016-04-02 20:26:15

您不需要memmove数据。realloc会自动这样做,并释放旧的缓冲区。因此,memmove正在从无效的(已经释放的)内存空间中进行复制。

票数 1
EN

Stack Overflow用户

发布于 2016-04-02 20:39:22

正如其他人所指出的,以你的方式使用记忆是不正确的。http://pubs.opengroup.org/onlinepubs/009695399/functions/realloc.html保留当前内容,并添加额外的内存,这样您就可以在需要时继续使用strcat或strcpy。

为了防止realloc()内存丢失,请使用临时buf,检查NULL,然后重新分配到原始的.

代码语言:javascript
复制
temp = realloc(temp, 20);
if(!temp)
{
     //handle error and exit
}
buf = temp;//transfer successfully allocated memory
....
//use newly reallocated buf
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36378213

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档