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

C++ Protobuf add创建对象的disks成员地址重复问题咨询

问题产生原因

  • Protobuf 中用 optional 修饰的复合消息类型字段,默认的 字段名() Getter 方法返回的是全局单例的默认不可变实例。你没有主动给 disks 字段赋值的前提下,所有未初始化的 optional Disks 字段都会返回同一个默认实例的常量引用,所以取到的地址自然完全相同。
  • 你感知到的"修改一个IpInfo的disks,所有IpInfo的disks都同步修改"是错误测试导致的错觉:这个默认实例本身是只读的,正常调用修改接口只会触发写时复制逻辑,仅修改当前操作的对象对应的字段,不会影响其他实例。

解决方法

如果需要给每个IpInfo配置独立的disks内容,使用Protobuf提供的mutable_字段名()方法获取当前对象专属的disks实例指针即可:

GetIdKeyValueResp resp;
for (int i = 0; i < 10; i++) {
  IpInfo* ipinfo = resp.add_ips();
  // 调用mutable_disks主动为当前IpInfo分配独立的disks内存空间
  Disks* disks = ipinfo->mutable_disks();
  cout << disks << endl;
  // 后续直接操作disks指针修改内容,不同IpInfo的disks完全独立互不影响
}

运行以上代码后输出的10个地址会完全不同,不会再出现修改互相干扰的问题。

注意事项

  • 只有主动调用mutable_xxx()、set_allocated_xxx()接口给optional复合字段赋值后,该字段才会分配专属的内存空间,否则都会指向全局默认只读实例。
  • 禁止对disks()返回的常量引用强制转型后修改,会触发未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 21:57:00