Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在堆栈末尾进行分配的递归函数_C++_Arrays_Pointers_Ubuntu_Recursion - Fatal编程技术网

C++ 在堆栈末尾进行分配的递归函数

C++ 在堆栈末尾进行分配的递归函数,c++,arrays,pointers,ubuntu,recursion,C++,Arrays,Pointers,Ubuntu,Recursion,好吧,我遇到了一个奇怪的问题。我正在实现一个叫做埃拉托斯尼筛的算法。我有一个函数primeArray\u r,它递归地通过我生成的数组工作,然后在它结束时,它在堆上创建一个新数组,然后在它向下通过堆栈时开始填充它,最后返回指向数组开头的指针。如果您想知道我为什么直接递增指针,这是作业的一个要求。我在运行时会遇到问题,但这取决于我使用的环境。 在Windows中,它似乎在没有警告的情况下爆炸,有时会重复完全相同的序列。在Ubuntu Linux中,这非常奇怪。它更稳定一点,如果它工作一次,它将在同

好吧,我遇到了一个奇怪的问题。我正在实现一个叫做埃拉托斯尼筛的算法。我有一个函数
primeArray\u r
,它递归地通过我生成的数组工作,然后在它结束时,它在堆上创建一个新数组,然后在它向下通过堆栈时开始填充它,最后返回指向数组开头的指针。如果您想知道我为什么直接递增指针,这是作业的一个要求。我在运行时会遇到问题,但这取决于我使用的环境。 在Windows中,它似乎在没有警告的情况下爆炸,有时会重复完全相同的序列。在Ubuntu Linux中,这非常奇怪。它更稳定一点,如果它工作一次,它将在同一个输入上工作多次,但根据输入的不同,它会失败。例如,我在裸机上安装的Ubuntu 14.04 64位。如果上限为5、9、13、17,程序将崩溃。。。或者任何数字(N*4)+1,在我的虚拟安装Lubuntu 13.10 32位上,如果上限为2、4、6、8,它将崩溃。。。或任何N*2的数字。错误消息基本相同:

Program5.1: malloc.c:2372: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
Aborted (core dumped)
唯一的区别是行号,Lubuntu 13.10中的malloc.c.2369和Ubuntu 14.04中的2372 似乎是我在第116行的内存分配过程中造成了某种崩溃:
primeArray=newint[primeCount]

我想知道这是我自己的错误,还是在递归堆栈末尾分配内存时发现了一些暴露的错误

#include<iostream>
#include <math.h>
using namespace std;

int* makeArray(int);
int firstZero (int*);
void circleCross(int*, int*, int);
void circleAll(int*, int*);
int* primeArray(int*, int*, int&, int);
int* primeArray_r(int*, int*, int*, int&, int);

int main(){
    //display a title
    cout << "The Sieve of Eratosthenes" << endl;
    cout << "gives you all the primes you want!" << endl;
    cout << "(in the range you specify...)" << endl;
    //ask the user to specify a range of positive numbers
    char repeat;
    int low;
    int high;
    int size;
    do{
        do{
            low = 0;
            high = 0;
            while (low < 1){
                cout << "Give me the lower bound" << endl;
                cin >> low;
            }
            while (high < 1){
                cout << "Give me the upper bound" << endl;
                cin >> high;
            }
        }while (low > high);
        size = high + 1;
        int* array = makeArray(size);
        int *end = array + size;
        int ix;
        double root = sqrt(high);
        do{
            ix = firstZero(array);
            if (ix <= root)
                circleCross(array, end, ix);
        }while ( ix < root);
        circleAll(array, end);
        array += low;
        cout << "Found all the primes!" << endl;
        int primeCount = 0;
        int* arrayPrime = primeArray(array, end, primeCount, low);
        cout << "Here's your primes!" << endl;
        int *primeEnd = arrayPrime + primeCount;
        while(arrayPrime < primeEnd){
            cout << *arrayPrime << endl;
            ++arrayPrime;
        }
        cout << "Enter 'y' to go or any other character to stop" << endl;
        cin >>  repeat;
    } while(repeat == 'y');

    return 0;
}

int* makeArray( int size){
    int *array;
    array = new int[size];
    int *firstAddress = array;
    *array = -1;
    *(++array) = -1;
    int *end = firstAddress + size;
    while (array < end){*(++array) = 0;}
    return firstAddress;
}

int firstZero ( int* array){
    int *ix;
    for (ix = array; (*ix); ++ix);
    int zero = ix - array;
    return zero;
}

void circleCross( int* array, int *end, int factor){
    array += factor;
    *array = 1;
    array += factor;
    while(array < end){
        *array = -1;
        array += factor;
    }
}

void circleAll( int* array, int *end){
    while (array < end){
        if (*array==0)
            *array=1;
        ++array;
    }
}

int* primeArray( int* array, int *end, int &primeCount, int low){
    primeCount=0;
    int *beginning = array;
    int *primeArray = primeArray_r(array, beginning, end, primeCount, low);
    return primeArray;
}

int* primeArray_r(int * array, int * beginning, int *end, int &primeCount, int low){
    int *primeArray;
    if (array == end){
        primeArray = new int[primeCount];
        primeArray += primeCount;
    }
    else{
        if (*array == 1){
            int position = primeCount; 
            ++primeCount;
            primeArray = primeArray_r((array+1), beginning, end, primeCount, low);
            --primeArray;
            *primeArray = array - beginning + low;
        }
        else{
            primeArray = primeArray_r((array+1), beginning, end, primeCount, low);
        }
    }
    return primeArray;
}
#包括
#包括
使用名称空间std;
int*makeArray(int);
int firstZero(int*);
无效循环交叉(int*,int*,int);
无效循环(int*,int*);
int*素数数组(int*,int*,int&,int);
int*素数数组(int*,int*,int*,int&,int);
int main(){
//显示标题

cout在makeArray()中,您正在数组后面写入一个0(
,而(array
),这会产生未定义的行为。因此,这很可能是导致崩溃的原因,因为这也与分配内存有关。

我很确定问题出在代码中,因为程序会使用断言停止,这通常意味着用户代码行为不正常,您会说它在不同的系统上崩溃。我还看到你没有释放你的新数组,所以你有一个内存泄漏和指针算法(特别是对分配内存的指针)这总是很棘手。但是我没有进一步调查就找不到罪魁祸首,所以我只是在评论中给出了我的想法。我会用2和5这样的小值手动跟踪,以确认实现符合预期。然后使用调试器逐步检查代码,跟踪所有变量的行为是否符合预期在这个过程中有很多事情需要跟踪。行为表明递归的基本情况不正确。Thad做到了,我更改了代码,使其在增量后而不是增量前工作,并按预期工作