为什么这段代码只会针对某些情况提供段错误?

时间:2016-08-01 16:37:24

标签: c++ segmentation-fault subset-sum

我正在尝试编写子集和的Word-RAM版本。 (这是一个基本的dp算法,算法本身对于确定代码问题并不重要)。这是重现我认为错误所需的最小代码:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>


// get bit #bitno from num. 0 is most significant.
unsigned int getbit(unsigned int num, int bitno){

    unsigned int w = sizeof(int)*8;  //for regular word.
    int shiftno = w-bitno-1;
    unsigned int mask = 1<<shiftno;
    unsigned int maskedn = num&mask;
    unsigned int thebit = maskedn>>shiftno;
    return thebit;
}

/* No boundary array right shift */
unsigned int* nbars(unsigned int orig[], unsigned int x){

    int alength = sizeof(orig)/sizeof(orig[0]);
    unsigned int b_s = sizeof(int)*8;
    unsigned int * shifted;
    shifted = new unsigned int[alength];
    int i;
    for(i=0;i<alength;i++){
        shifted[i] = 0;
    }

    unsigned int aux1 = 0;
    unsigned int aux2 = 0;

    int bts = floor(x/b_s);
    int split = x%b_s;
    i = bts;
    int j = 0;
    while(i<alength){
        aux1 = orig[j]>>split;
        shifted[i] = aux1|aux2;
        aux2 = orig[j]<<(b_s-split);
        i++;j++;
    }

    return shifted;
}

/* Returns true if there is a subset of set[] with sum equal to t */
bool isSubsetSum(int set[],int n, int t){
    unsigned int w = sizeof(int)*8;  //for regular word.
    unsigned int wordsneeded = ceil(double(t+1)/w);
    unsigned int elements = n;
    //Create table
    unsigned int table[elements][wordsneeded];
    int c,i;
    //Initialize first row
    for(i=0;i<wordsneeded;i++){
        table[0][i] = 0;
    }
    table[0][0] = 1<<(w-1);
    //Fill the table in bottom up manner
    int es,ss,ai;
    for(c=1;c<=elements; c++){

        unsigned int *aux = nbars(table[c-1],set[c-1]);
        for(i=0;i<wordsneeded;i++){
            table[c][i] = table[c-1][i]|aux[i];
        }
        }

    if((table[elements][wordsneeded-1]>>((w*wordsneeded)-t-1))&1 ==1){

         return true;
     }return false;
}


int main(){


    int set[] = {81,80,43,40,30,26,12,11,9};
    //int sum = 63;
    int sum = 1000;

    int n = sizeof(set)/sizeof(set[0]);
    if (isSubsetSum(set,n,sum) == true)
     printf("\nFound a subset with given sum\n");
  else
     printf("\nNo subset with given sum\n");
  return 0;
}

确定。所以,如果我运行目标总和为63的示例,它就可以正常工作。给出正确的答案,True,如果我运行代码打印子集,它会打印出正确的子集。但是,如果我将总和更改为更大的一个,比如代码中的1000,我会收到以下错误:

Program received signal SIGSEGV, Segmentation fault.
0x0000000000400af1 in isSubsetSum (set=0x0, n=0, t=0) at redss.cpp:63
63          unsigned int *aux = nbars(table[c-1],set[c-1]);

来自gdb。我真的不明白为什么它只会因为更大的金额而失败,因为这个过程应该是一样的......我错过了一些明显的东西吗?任何帮助都会很棒!!!

0 个答案:

没有答案