这个StackOverFlowException要求指针正确工作吗?

Does this StackOverFlowException require pointers to correctly work?

本文关键字:工作 指针 StackOverFlowException 这个      更新时间:2023-10-16

我编写了一个程序,通过从.txt文件中读入,然后将输出放到一个单独的.txt文件中来搜索回文。

对于大约50个左右的字符,它可以正常工作。但是,如果我复制并过去大量的单词到。txt文件上供它阅读,在运行时它会说"进程因StackOverFlowException而终止"。然后打开一个名为chkstk的文件。Asm和有一个箭头指向一个叫做"test dword PTR [eax], eax;调查页面"。接下来,弹出一个中断并继续选项框,并表示:"类型为‘System’的未处理异常。StackOverflowException' occurred in palindrone.exe"

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

#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;
}

在C/c++中有堆栈和堆。堆栈通常是固定大小的内存段,可能比您想象的要小(默认值可能在1-2MB左右),堆是内存的动态部分,它会一直增长,直到超过服务器上的总逻辑RAM。

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

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

说了这么多,我应该提一下,如果您切换到指针,您可能会看到小的好处。这是因为堆栈帧的大小取决于函数参数和局部变量的大小。指针可能比您传入的其他结构更小,并可能导致更小的堆栈帧。但是,这并不是问题的根本原因。