对 char 数组的操作如何导致堆栈溢出?

How does manipulation of a char array cause a stack overflow?

如果有明显的缺陷,我很抱歉。我对内存还很陌生,所以我对堆栈溢出的工作原理有一些了解,据我所知,我所做的任何事情都不会导致堆栈溢出。我所做的只是更改字符串中的字符。

我知道数组是指针,但更改值会导致堆栈溢出吗?

相关函数如下:

char base[] = "aaaaa";
void changeLetters(int position) { // Stack overflow happens around here
    if (base[position] != 'z') {
        base[position]++;
    }

    // When I include a cout here, I also get a stack overflow

    if (position == 4 && base[position] != 'z') {
        changeLetters(position);
    }
    else if (base[position] == 'z' && position != 0) {
        base[position] = 'a';
        changeLetters(position - 1);
    }
    else if (position < 4) {
        changeLetters(position + 1);
    }
}

当没有 std::cout 时,我得到

Unhandled exception at 0x767C3210 (KernelBase.dll) in passwordCracker.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x01002FFC).

否则

Unhandled exception at 0x009C38B9 in passwordCracker.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x006D2F8C).

编辑: 该函数在主循环中调用。传递的值是字符串 (4) 的长度,它会一直运行下去。我没有提到的一件奇怪的事情是,如果我循环使用较少数量的字母(a、b、c、d),它会完美地工作,但如果我让它循环遍历字母表,我只会收到堆栈溢出。

您的代码正在遍历由字母 a-z 组成的所有长度为 5 的字符串。这本身不是问题,但是您必须确保最大调用深度不会太大。

changeLetters 的每次迭代中,您最多增加一个字母一次,然后再次调用 changeLetters,您最多进行一次这样的调用。

因此,您的调用图是完全线性的,对于每个 26^5 字符串,您都在进行另一个深度递归调用,因此最后的调用堆栈将有那么大。问题是,这是一个非常大的数字 26^5 = 11881376,可能很容易大于您可能使用的堆栈 space。

您需要将线性调用图变成一个带有分支的调用图,例如在当前字符的位置上使用循环而不是每次调用 changeLetters

递归不是无限的,但它很深。深度足以炸毁堆栈。

函数每次递增一个字母时都使用递归。因为有 5 个字符,每个字符有 26 个可能的值,所以递归是 265 = 11881376 层深。我不确定您的堆栈有多大,但它不足以处理那么多级别。所以你得到一个堆栈溢出。

切换到使用嵌套循环的迭代解决方案。