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

将结构体复制到map数组元素时触发访问违规的问题排查与解决

问题解决与验证方案

错误原因分析

你遇到的访问违规核心原因是:std::map<int, hdr(*)[20]> SP; 定义的map值类型是指向20个hdr结构体的数组的指针,当通过SP[0]访问键为0的元素时,map会自动插入一个默认构造的指针值——而指针类型的默认值是nullptr(空指针)。此时SP[0][0]相当于对空指针做解引用操作,直接触发内存访问违规。

问题1:解决访问违规的方法

需要为map中的每个键值对分配实际的数组内存,具体操作如下:

  1. 访问map的键时,先检查该键是否存在;若不存在,用new分配一块能容纳20个hdr的数组内存,再将指针存入map。
  2. 确保后续操作的是已分配有效内存的指针。

修改后的示例代码:

#include <iostream>
#include <map>
#include <cstring>

int main()
{
    struct hdr {
        int cpi_length = 42;
    };

    hdr* this_hdr = new hdr; // 改用hdr*而非void*,提升类型安全性
    std::map<int, hdr(*)[20]> SP;

    // 检查键0是否存在,不存在则分配内存
    if (SP.find(0) == SP.end()) {
        SP[0] = new hdr[20]; // 分配20个hdr的数组,返回的指针符合hdr(*)[20]类型
    }

    std::cout << sizeof(hdr) << std::endl; // 输出4
    std::cout << sizeof(this_hdr) << std::endl; // 输出当前平台指针大小(如4或8)
    std::cout << sizeof(SP[0][0]) << std::endl; // 输出80(20*4)

    // 此时SP[0][0]指向有效内存,可安全执行memcpy
    std::memcpy(SP[0][0], this_hdr, sizeof(hdr));
    std::cout << SP[0][0]->cpi_length << std::endl; // 输出42,验证复制成功

    // 释放内存避免泄漏
    delete this_hdr;
    delete[] SP[0];
    SP.clear();

    return 0;
}

问题2:验证功能实现的方法

可以通过以下几种方式验证复制操作是否符合预期:

  • 直接打印成员值:打印目标缓冲区中结构体的cpi_length成员,确认其值与源对象一致(比如示例中的42)。
  • 内存内容对比:使用std::memcmp比较源对象和目标缓冲区的内存内容,返回值为0则说明内存完全一致:
    if (std::memcmp(SP[0][0], this_hdr, sizeof(hdr)) == 0) {
        std::cout << "内存复制成功" << std::endl;
    }
    
  • 检查目标地址有效性:判断SP[0]是否为nullptr,确保操作的是有效内存空间。

内容的提问来源于stack exchange,提问作者Nathan Goedeke

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 00:46:31