在堆栈末尾分配的递归函数

时间:2014-04-18 06:32:20

标签: c++ arrays pointers ubuntu recursion

好的,我遇到了一个奇怪的问题。我正在实施一种称为eratosthenes筛的算法。我有一个函数primeArray_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 = new int[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;
}

1 个答案:

答案 0 :(得分:0)

在makeArray()中,您在数组(while (array < end){*(++array) = 0;})之后写入0,这会创建未定义的行为。所以这很可能是你崩溃的原因,因为这也与分配内存有关。