You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++请求币安API报错Run-time check failure #2 root变量栈损坏

报错原因

该报错是Windows平台VS编译器开启运行时栈检查(/RTCs)时触发的典型内存错误,提示栈上root变量周边的内存被非法写入,你的代码存在3个直接触发问题的逻辑错误:

  • 跨类型调用JsonCpp接口触发未定义行为:币安/api/v3/time接口返回的serverTime字段为64位整数类型(示例返回:{"serverTime":1719876543210}),你调用root.get("serverTime","")时传入的默认值为字符串字面量,后续直接对返回的整型Json::Value对象调用asString(),跨类型强转会导致JsonCpp内部内存操作越界,直接破坏栈上root周边的内存。
  • Json解析接口使用不符合约定:你调用reader.parse(readBuffer.c_str(), root)时传入const char*类型指针,会匹配到JsonCpp旧版本中「就地修改输入缓冲区」的parse重载,该版本接口要求传入可写的字符缓冲区,c_str()返回的只读指针不符合接口要求,容易引发越界写入。
  • 缺少请求有效性校验:你没有校验curl_easy_perform的返回值,也没有校验HTTP响应状态码,如果请求失败(网络不通、证书错误、接口限流等),readBuffer中存储的不是合法JSON,后续解析逻辑会触发不可预期的内存错误。

另外代码存在一个易引发逻辑问题的不规范写法:main函数开头已经定义了CURLcode res变量,在curl执行块内又重复定义同名res变量造成变量遮蔽,容易导致后续逻辑判断出错。

修复方案

按以下步骤修改代码即可解决问题:

  • 调整Json解析调用方式,直接传入std::string类型的响应内容作为parse输入,避免使用要求可写缓冲区的重载接口
  • 读取serverTime字段时先校验字段存在性、类型匹配性,按64位整数类型读取值后再转为字符串输出,禁止对非字符串类型的Json::Value直接调用asString()
  • 增加curl请求返回值、HTTP状态码校验逻辑,所有错误分支都要正确清理curl资源,避免资源泄漏
  • 移除重复定义的res变量,补充curl全局初始化/清理逻辑
  • 如果修改完代码仍报相同栈错误,重新编译你使用的JsonCpp源码,确保项目引用的头文件、链接的库为同版本编译产物,且项目的C/C++运行时库配置(MT/MTd/MD/MDd)和JsonCpp编译时的配置完全一致,避免因对象内存布局不匹配引发越界。

修复后的完整可运行代码:

#include <iostream>
#include <curl/curl.h>
#include "json/json.h"
#include <string>

size_t WriteCallback(char* contents, size_t size, size_t nmemb, void* userp)
{
    ((std::string*)userp)->append(contents, size * nmemb);
    return size * nmemb;
}

int main()
{
    CURL* curl;
    CURLcode res;
    std::string readBuffer;
    Json::Value root;
    Json::Reader reader;
    long http_code = 0;

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();
    if (curl) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://api.binance.com/api/v3/time");
        curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
        curl_easy_setopt(curl, CURLOPT_WRITEDATA, &readBuffer);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2L);
        curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10L);

        res = curl_easy_perform(curl);
        // 校验curl请求执行结果
        if (res != CURLE_OK) {
            std::cout << "curl request failed: " << curl_easy_strerror(res) << std::endl;
            curl_easy_cleanup(curl);
            curl_global_cleanup();
            return 1;
        }
        // 校验HTTP响应状态码
        curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
        if (http_code != 200) {
            std::cout << "http request error, code: " << http_code << ", response: " << readBuffer << std::endl;
            curl_easy_cleanup(curl);
            curl_global_cleanup();
            return 1;
        }

        // 传入string对象调用parse接口
        bool parsingSuccessful = reader.parse(readBuffer, root);
        if (!parsingSuccessful)
        {
            std::cout << "Failed to parse response: "
                << reader.getFormattedErrorMessages() << std::endl;
            curl_easy_cleanup(curl);
            curl_global_cleanup();
            return 1;
        }
        // 按64位整数类型读取时间戳,转字符串输出
        if (root.isMember("serverTime") && root["serverTime"].isInt64()) {
            std::cout << std::to_string(root["serverTime"].asInt64()) << std::endl;
        } else {
            std::cout << "serverTime field missing or type mismatch" << std::endl;
        }

        curl_easy_cleanup(curl);
    }
    curl_global_cleanup();
    return 0;
}

内容的提问来源于stack exchange,提问作者Remì1998

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 23:30:52