【问题标题】:Function exceeds stack size, consider moving some data to heap (C6262)函数超出堆栈大小,考虑将一些数据移动到堆中(C6262)
【发布时间】:2019-10-20 21:01:13
【问题描述】:

我正在尝试通过制作密码生成器来学习 C++,当我快完成时,我收到了一个警告(警告 C6262 函数使用 '20044' 字节的堆栈:超过 /analyze:stacksize '16384'。考虑移动一些要堆的数据。) 而且由于我是 C++ 的初学者,现在才掌握基础知识,我不知道该怎么做。

由于我在函数中有 2 个数组,我试图将它们移出主函数,它确实降低了它正在使用的字节数 (20100),它仍然太高了。我尝试阅读 Microsoft 的错误指南,但我不了解堆或将所述数据移动到 C++ 中的堆

代码如下:

#include <iostream>
#include <random>
using namespace std;

class Randomer {
    // random seed by default
    std::mt19937 gen_;
    std::uniform_int_distribution<size_t> dist_;

public:
    /*  ... some convenient ctors ... */

    Randomer(size_t min, size_t max, unsigned int seed = std::random_device{}())
        : gen_{ seed }, dist_{ min, max } {
    }

    // if you want predictable numbers
    void SetSeed(unsigned int seed) {
        gen_.seed(seed);
    }

    size_t operator()() {
        return dist_(gen_);
    }
};

string alphabet{ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
                          'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
                          'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
                          'k', 'l', 'm', 'n','o','p', 'q', 'r', 's', 't', 'u', 'v',
                          'w', 'x', 'y', 'z' };
string specialchars{ ' ','!','#','$', '%', '&','(',')','*','+','-','.','/',':',';','<','=','>','?','@' };
Randomer rand1{ 0,2 };
Randomer randint{ 0,9 };
Randomer randalpha{ 0,26 };
Randomer randspecial{ 0,20 };
int main()
{
    while (true) { //This loop is to restart the program if an invaild response is detected.
        int i;
        int lengthofpassword = 8;

        cout << "Do you want to generate a password or to type in a existing password to make it stronger?\n\n(1 for generation, 2 for existing password)\n";
        cin >> i;
        int g = 0;
        if (i == 1) {
            cout << "\nWhat is the length of the password?\n";
            cin >> lengthofpassword;
            while (g <= lengthofpassword -1) {

                //if (rand() == 0) {//numb
                //  cout << randint();
                //}
                //else if (rand() == 1) {//letter
                //  cout << alphabet[randalpha()];
                //}
                switch (rand1())
                {
                case 0:
                    cout << alphabet[randalpha()];
                    break;
                case 1:
                    cout << randint();
                    break;
                case 2:
                    cout << specialchars[randspecial()];
                    break;
                default:
                    break;
                }

                g = g + 1;
                //cout << "\n\n" << g << "\n\n";
            }
            cout << "\n";
            system("pause");
            return 0;

        }
        else if (i == 2) {
            cout << "\n";
            system("pause");
            return 0;
        }
        else {
            cout << "\n";
            cout << "Invaild Response!\n";
        }
    }
//  system("pause");
    return 0;
}

尝试为 stackoverflow 压缩它没有奏效。 虽然它还没有损坏并且按预期工作,但我觉得我应该现在而不是以后学习这类东西。

【问题讨论】:

  • 这是整个代码。
  • 我不知道这是否是原因,但我在 Visual Studio 2019 控制台应用程序中制作了这个项目。您是否使用不同的程序/项目类型?
  • 啊,我知道发生了什么。当我试图在堆栈上发布代码并忘记将它们更改回来时,我尝试将数组中的 ' 替换为 "。它们应该是字符串字母{ 'A', 'B' 等
  • 我已经更改了代码。

标签: c++


【解决方案1】:

std::mt19937 伪随机数生成器实际上是一个 巨大 对象,您在循环中创建了很多对象。您应该做的是在开始时创建其中一个并在Randomer 对象之间共享它,例如通过在构造函数中传递一个指针。 (您可以将它们或 Randomer 对象移动到堆中,但创建大量它们只是浪费性能,没有充分的理由拥有多个。)

【讨论】:

    【解决方案2】:

    将某些东西从堆栈移动到堆基本上是使用new 显式分配新对象,而不是声明变量。

    在您的情况下,您可以用Randomer* xxx = new Randomer{...} 替换四个Randomer xxx 变量,并在循环结束时将其删除。虽然在循环内重新创建 PRNG 没有多大意义,也许您应该将 Randomer 对象移到 main() 之外。

    【讨论】:

    • 如果你真的要将Randomer移动到堆上,你应该使用auto xxx = std::make_unique&lt;Randomer&gt;(...);或类似的,这样对象在块的末尾仍然被正确地销毁。然而,就速度和随机数质量而言,共享一个 PRNG 是一种更好的方法。
    猜你喜欢
    • 2017-05-11
    • 1970-01-01
    • 1970-01-01
    • 2021-12-07
    • 2022-07-06
    • 2012-06-26
    • 2019-05-04
    • 1970-01-01
    • 2014-05-12
    相关资源
    最近更新 更多