首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在代码中使用std::bad_alloc的原因是什么?

在代码中使用std::bad_alloc的原因是什么?
EN

Stack Overflow用户
提问于 2022-05-27 07:50:20
回答 1查看 149关注 0票数 0

最近我写了这段代码,我注意到这里的某个地方

terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc

这是我的代码:

代码语言:javascript
复制
namespace logger {
    set<string> pendingLogs;
    bool isDebugEnabled = false;
    mutex logMutex;

    inline void add_log_to_pending(const string &text) {
        lock_guard<mutex> guard(logMutex);
        cout << "[Logger] Adding: " << text << endl;

        pendingLogs.insert(text);
    }

    inline string grab_logs() {
        string collector;
        lock_guard<mutex> guard(logMutex);
        if (pendingLogs.empty()) return collector;

        for (const auto& item: pendingLogs) {
            collector += item + "\n";
        }

        pendingLogs.clear();
        return collector;
    }
}

启动线程代码:

代码语言:javascript
复制
std::thread log_composer_thread(&log_composer_callable);
log_composer_thread.detach();

函数线程代码:

代码语言:javascript
复制
[[noreturn]] void log_composer_callable() {
    logger::log_debug("Log composer thread started..");
    while (true) {
        const string &logs = logger::grab_logs();
        if (logs.empty()) {
            std::this_thread::sleep_for(std::chrono::milliseconds(1000));
            continue;
        }

        //send logic
    }
}

是什么导致了这个错误?我认为这与curl库有关,但当我禁用整个日志逻辑时,所有错误都消失了,所以我认为错误在记录器代码中。

编辑1:

代码语言:javascript
复制
inline std::vector<unsigned char>
rsa_encrypt_pubkey(EVP_PKEY *pubKey, unsigned char *toEncrypt, size_t toEncryptLength, bool eraseInputArray) {
    size_t outlen;
    if (toEncryptLength > 256) {
        logger::add_log_to_pending("Error: rsa_encrypt_pubkey: toEncryptLength > 256");
        return {};
    }

    //init the cipher context for encryption using the public key
    EVP_PKEY_CTX *enc_ctx = EVP_PKEY_CTX_new(pubKey, nullptr);
    EVP_PKEY_encrypt_init(enc_ctx);
    EVP_PKEY_CTX_set_rsa_padding(enc_ctx, RSA_PKCS1_OAEP_PADDING);
    EVP_PKEY_CTX_set_rsa_oaep_md(enc_ctx, EVP_sha256());

    //determine output length
    if (!EVP_PKEY_encrypt(enc_ctx, nullptr, &outlen, toEncrypt, toEncryptLength)) {
        logger::add_log_to_pending("Error: EVP_PKEY_encrypt | " + string(ERR_error_string(ERR_get_error(), nullptr)));
        return {};
    }

    std::vector<unsigned char> encrypted(outlen);

#if debug_mode_advanced == 1
    cout << "Output length: " << outlen << " toEncryptLenght: " << toEncryptLength << endl;
    cout << ERR_error_string(ERR_get_error(), nullptr) << endl;
#endif

    //final encrypt call
    if (!EVP_PKEY_encrypt(enc_ctx, &encrypted[0], &outlen, toEncrypt, toEncryptLength)) {
        logger::add_log_to_pending("Error: EVP_PKEY_encrypt | " + string(ERR_error_string(ERR_get_error(), nullptr)));
        return {};
    }

    //clean up
    EVP_PKEY_CTX_free(enc_ctx);
    if (eraseInputArray) free(toEncrypt);

    return encrypted;
}

那个导致问题的代码,这里有什么问题?

编辑2:

代码语言:javascript
复制
inline vector<unsigned char>
rsa_encrypt_rewrite(unsigned char *in, size_t inlen, EVP_PKEY *key, bool eraseInputArray) {
    try {
        EVP_PKEY_CTX *ctx;
        ENGINE *eng;
        unsigned char *out;
        size_t outlen;

        if (inlen > 256) {
            logger::add_log_to_pending("Error: rsa_encrypt_pubkey: toEncryptLength > 256");
            return {};
        }
        ctx = EVP_PKEY_CTX_new(key, eng);
        if (!ctx) {
            logger::add_log_to_pending(
                    "Error: EVP_PKEY_CTX_new | " + string(ERR_error_string(ERR_get_error(), nullptr)));
            return {};
        }
        /* Error occurred */
        if (EVP_PKEY_encrypt_init(ctx) <= 0) {
            logger::add_log_to_pending(
                    "Error: EVP_PKEY_encrypt_init | " + string(ERR_error_string(ERR_get_error(), nullptr)));
            return {};
        }
        /* Error */
        if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_OAEP_PADDING) <= 0) {
            logger::add_log_to_pending(
                    "Error: EVP_PKEY_CTX_set_rsa_padding | " + string(ERR_error_string(ERR_get_error(), nullptr)));
            return {};
        }
        /* Error */

/* Determine buffer length */
        if (EVP_PKEY_encrypt(ctx, nullptr, &outlen, in, inlen) <= 0) {
            logger::add_log_to_pending(
                    "Error: EVP_PKEY_encrypt | " + string(ERR_error_string(ERR_get_error(), nullptr)));
            return {};
        }
        /* Error */

        out = (unsigned char *) OPENSSL_malloc(outlen);

        if (!out) {
            logger::add_log_to_pending("Error: OPENSSL_malloc");
            return {};
        }
        /* malloc failure */

        if (EVP_PKEY_encrypt(ctx, out, &outlen, in, inlen) <= 0) {
            logger::add_log_to_pending(
                    "Error: EVP_PKEY_encrypt | " + string(ERR_error_string(ERR_get_error(), nullptr)));
            return {};
        }

        EVP_PKEY_CTX_free(ctx);
        if (eraseInputArray) free(in);

        vector<unsigned char> encrypted(out, out + outlen);
        OPENSSL_free(out);
        return encrypted;
    } catch (const std::exception &e) {
        logger::add_log_to_pending("Error: rsa_encrypt_rewrite general exception: " + string(e.what()));
        return {};
    }

}

那密码似乎没问题吧?bad_alloc不应该出现吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-05-28 10:13:49

看起来问题就在代码的这一部分:

代码语言:javascript
复制
if (!EVP_PKEY_encrypt(enc_ctx, nullptr, &outlen, toEncrypt, toEncryptLength)) {
    logger::add_log_to_pending("Error: EVP_PKEY_encrypt | " + string(ERR_error_string(ERR_get_error(), nullptr)));
    return {};
}

std::vector<unsigned char> encrypted(outlen);

考虑到EVP_PKEY_encrypt()也可能返回一个负值的错误。你把所有不是零的东西都当作成功对待。但是,如果它失败了,outlen可能不会被正确初始化,在这种情况下,它可能包含一个巨大的数字,这会导致encrypted的构造函数耗尽内存,抛出std::bad_alloc

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72402152

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档