StackOverFlowException是否需要指针才能正常工作?

时间:2013-04-18 02:18:16

标签: c++ visual-c++

我通过从.txt文件读取中,然后将输出到一个单独的.txt文件由一个程序,它搜索回文。

它的工作原理与大约50个左右的字符一样。但是,如果我过去大量的单词复制到.txt文件,它读取,在运行时它会说“进程被终止由于StackOverFlowException”。然后它打开一个名为chkstk.asm的文件,并有一个箭头指向一个叫做“test dword ptr [eax],eax; probe page”的东西。接下来,一个框出现一个break和continue选项,并说:“palindrone.exe中发生了'System.StackOverflowException'类型的未处理异常”

我目前正在努力改变使用指针等,并可能将内容存储在向量中。但是,我仍然不确定错误的原因是什么,我想知道为什么它正在起作用,需要改变什么,所以我可以让它读取和处理大块文本。没有指针说明它工作不正确的原因吗?

#include <iostream>
#include <string>
#include <ctype.h>
#include <iterator>
#include <algorithm>
#include <fstream>

using namespace std;

/**
    Recursivly reverses a string
    @ param word, the word being entered
    @ last_char, the last character currently in the string
    @ go, the recursive function to return the character and continue inside itself
**/
string string_reverse(string word)
{
    if (word.length() - 1 > 0)
    {
        char last_char = word[word.length()-1];
        word.erase(word.length()-1);
        string go = string_reverse(word);
        return go.insert(0, 1, last_char);
    }
    else  
        return word.substr(0,1);
}

/**
@param in, the input as the original string
@param la, the reverse string
**/
bool equals(string in, string la)
{
    if(in == la)
        return true;
    else 
        return false;
}

/**
processes the pal
**/
void process_pal(ofstream &outfile, string in, string la, bool sam)
{
    if (sam == true)
    {
        outfile << in << " EQUAL to backwards: " << la << "\n";
    }
    else
        outfile << in << " NOT equal to backwards: " << la << "\n";
}

/**
    Removes all Numbers, white spaces, and invalid symbols with !isalpha
    @param sentence, the sentence being entered
    @ it, the iterator to iterator through the sentence checking for invlaid sysmbols
**/
string remover(string sentence)
{
    string::iterator it = sentence.begin();

    while (it != sentence.end())
    {
         while( it != sentence.end() && !isalpha(*it))
         {
             it = sentence.erase(it);
         }
         if (it != sentence.end())
             ++it;
    }
return sentence;
}

/**
    Increments to find paladrome by starting at 3 from 0, then moving right 1 by 3 each time util
    it goes to the end. Once it hits the end, it will increment by four and do the same thing till
    it has become the full length of the text.
**/
void find_pal(ofstream &outfile, string input, int pos, int lin)
{
    int max_length = input.length()+1;
    int pos_last = max_length - lin;
    if(lin < input.length()){
        string sub_fwrd = input.substr(pos,lin);
        string sub_bck = string_reverse(sub_fwrd);
        bool same = equals(sub_fwrd, sub_bck);
        process_pal(outfile, sub_fwrd, sub_bck, same);
        pos++;
        if (pos == pos_last){
            pos = 0;
            lin++;
        }
        find_pal(outfile, input, pos, lin);
}
}

int main()
{
    bool con = true;
    while (con == true)
    {
        string input;
        ifstream infile;
        infile.open ("file_read.txt");    
        getline(infile,input); // Saves the lines from the file in string input.
        infile.close();

        transform(input.begin(), input.end(), input.begin(), ::tolower); // Goes to all Lower Case

        string inputer = remover(input); // Removes unwanted symbols, numbers, spaces, etc
        input = inputer; // Updates our orignal string input

        ofstream outfile ("file_out.txt");
        int pos = 0;
        int lin = 3;
        find_pal(outfile, input, pos, lin); // Start the palindron function up to sift       through purmutations

        string full_input = string_reverse(input); // Final Purmutation of reverse
        bool same = equals(input, full_input);
        process_pal(outfile, input, full_input, same); // Final analyzing process_pal

        string go;
        outfile.close();    
        cout << "Continue? y/n " << endl; // Continue on or not
        getline(cin, go);
        if(go != "y")
            con = false;
    }
    system("pause");
    return 0;
}

1 个答案:

答案 0 :(得分:1)

在C / C ++中有一个堆栈和一个堆。堆栈通常是一个固定大小的内存段,可能比您想象的要小(默认值大约为1-2MB),堆是一个动态的内存段,直到你超过总逻辑RAM为止。服务器

对你的问题的简短回答是,每次嵌套函数调用时,都会在所谓的“堆栈帧”中分配更多的内存。因此,如果您有“主要呼叫A呼叫B再次呼叫B”,那么您有4个堆栈帧。如果你有一个随输入大小增长的递归方法,那么你将开始分配大量的堆栈帧,最终你会有一个堆栈溢出异常(堆栈的大小超过了固定的限制)。

因此,一般来说,问题的根本原因在于您的递归嵌套太深。有几种方法可以解决这个问题。注释中提到的一种常见方法是简单地放弃递归。另一种方法是使用tail recursion,避免在每次调用时添加新的堆栈帧,并允许您保留递归语义。

所有这一切,我应该提一下,如果你要切换到指针,你可能会看到的好处。这是因为堆栈帧的大小基于函数参数和局部变量的大小。指针可能小于您传入的其他结构,并且可能导致较小的堆栈帧。但是,这不是您问题的根本原因。