大型数据集的堆栈溢出异常

时间:2014-05-19 04:48:58

标签: c++ stack-overflow

我尝试解决这个问题:http://projecteuler.net/problem=201但是下面的程序会因较大的SET大小(> 20)而导致堆栈溢出异常。是否发生内存泄漏?你能指出哪里?如果以下实施涉及不良编码实践,请告诉我。我正在努力提高我的业余编程技巧。提前致谢。 编辑:我编辑了下面的代码。我现在没有任何堆栈溢出异常。但有人能建议我更好的算法吗?谢谢!

#include "stdafx.h"
#include <iostream>
#include <cmath>
#include <winsock2.h>
#define SET 100
#define SUBSET 50

class node
{
    public:
    int data;
    node* next;
};

using namespace std;
int sum(int A[SUBSET]);
void combCalc(int S[SET]);
bool search(node* head, int sum);
void appendIfUnique(int total, bool nullHeader);

int _tmain(int argc, _TCHAR* argv[])
{

    cout << "Hello World" << endl; 
   int S [SET];
   for(int i=1; i<=SET; i++)
   {
       S[i-1]= (int)pow((float)i,2);
   }
  combCalc(S);
   cin.get();
   return 0;
}

static node *head; 
static node *current = head;
void combCalc(int S[])
{
   int row=0, col=0;
   int elePos[SUBSET], B[SUBSET];
   bool nullHeader = true;
       for(int z=0; z<SUBSET; z++) // initializing elePos
       {
            elePos[z]=z;
       }

       bool notDone = true;
       while (notDone || col <(SUBSET-1))
       {B[col] = S[elePos[col]];
            if(col==(SUBSET-1)) //finished forming a subset
            {

                notDone = false;
                for(int q=(SUBSET-1); q>=0; q--) //incrementing from the last element
                {
                    if(elePos[q]<(SET-SUBSET+q)) //checking if the element has reached its maximum
                    {
                        notDone = true;
                        elePos[q]++;
                        for(int w=q+1; w<SUBSET; w++) //setting the trailing elements to its minimum
                        {
                            elePos[w]=elePos[q]+w-q;
                        }
                        break;
                    }
                }
                if(notDone){col=0;row++;}
                int total = sum(B);
                appendIfUnique(total,nullHeader);
                nullHeader = false;
            }
            else
            {
                col++;
            }
       }        
                int result = 0;
                for(node *pnode = head; pnode != current->next; pnode=pnode->next)
                    result = result + pnode->data;
                cout << result << endl; 
}


int sum(int A[])
{
    int total = 0;
    for(int i=0; i<SUBSET; i++)
    {
        total = total + A[i];
    }
    return total;
}

bool search(node* head, int sum)
{
    bool exists = false;
    node* pNode = head;
    while(pNode != NULL)
        {
            if(pNode->data == sum)  
            {
                exists = true;
                break;
            }
            pNode = pNode->next;
        }
    return exists;
}

void appendIfUnique(int total, bool nullHeader)
{
    if(nullHeader){head = NULL;}
                if(!search(head,total))
                {
                    node *temp;
                    /*temp=(node *) malloc(sizeof(node));*/
                    temp = new node();
                    temp->data = total;
                    temp->next = NULL;
                    if(head == NULL)
                    {
                        head = current = temp;
                    }
                    else
                    {
                        current->next = temp;
                        current = temp;
                    }
                }           
}

1 个答案:

答案 0 :(得分:1)

一些注意事项:

  1. 断点(在我的系统中:cygwin g ++)是SET = 18(17个作品)
  2. 问题是由于过多的递归[在调试器中运行]你对combCalc(S)的调用太多(在我的情况下,它在32K调用后死掉)。
  3. 正如评论中指出的那样,您应该重新考虑您的算法。与此同时,一个简单的修改是删除递归(因为它甚至不是一个正确的递归):

    int _tmain(int argc, _TCHAR* argv[])
    {
       cout << "Hello World" << endl; 
       int S [SET];
       for(int i=1; i<=SET; i++)
       {
           S[i-1]= (int)pow((float)i,2);
       }
       while(combCalc(S)) { } // <--- keep calling while combCalc is true
       cin.get();
       return 0;
    }
    

    通过使combCal()返回一个bool:

    bool combCalc(int S[]) // <--- MODIFY (check also the forward declaration)
    {
    
           ...
    
           if(notDone || col <(SUBSET-1))
           {
                ...
    
                return true; // <--- MODIFY return true... I need to keep calculating.
           }
           else
           {
                    int result = 0;
                    for(node *pnode = head; pnode != current->next; pnode=pnode->next)
                        result = result + pnode->data;
                    cout << result << endl;
                    return false; // <--- MODIFY return false.... we're done
           }
    }
    

    以上只是最低限度的修改。我甚至不确定它是否正确解决了问题,因为我还没有真正看过这个算法。

    你应该考虑:

    1. 使用较少强力算法
    2. 在combCalc()中移动while循环...这样你就可以进行一次调用......在这种情况下,你可能会删除静态变量并使它们成为简单的局部变量。
    3. 考虑不要将#define用于常量。
    4. 考虑使用STL结构......而不是您自己的本土结构。这将消除下面的一些问题。
    5. 考虑不使用malloc,而是使用new(更多C ++)
    6. 您没有使用free这意味着您分配的内存不会被释放。 (如果您使用的是delete,请使用new;如果您delete [] new [],请使用{{1}}
相关问题