C++ placement new 用法

本文探讨了在使用共享内存时,直接将string类型成员变量放置于共享内存中导致的段错误问题。分析了根本原因,并提供了通过placement new解决此问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

---源码---
struct Student
{
    string name;
    int age;
};
//创建共享内存的ID
#define MEM_ID    1234
//映射共享内存的大小,3个Student大小长
#define MEM_SIZE sizeof(Student)*3

//共享内存读取端
int main(void)
{
    //打开共享内存
    int shmid = shmget(MEM_ID, MEM_SIZE, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid == -1)
        err_exit("shmget");
    //映射共享内存,使用常量指针防止地址丢失
    Student * const cpstu = (Student*)shmat(shmid, NULL, 0);
    
    if (cpstu == reinterpret_cast<void*>(-1))
        err_exit("shmat");
    //访问数据
    Student *pstu = cpstu;
    //error:一旦访问string必出现段错误。
    printf("idx:%d,name:%s,age:%d\n",0, pstu[0].name.c_str(), pstu[0].age);
        ......
---end----

问题描述:
每次访问Student对象中的string成员就会导致段错误。

问题分析:
根本原因在于,string字符串必须要使用默认的构造函数才能正确使用
所以,当直接使用共享内存作为string时,就会出现错误!
实际上,不只是共享内存,使用malloc分配的内存来作为string使用时,也会导致相同的错误
只用使用new构建Student对象,或者直接在栈空间中定义Student对象,或者定义全局Student对象时,
这几种情况下,都会调用默认的构造函数来构建string对象。

解决方案:
使用placement new(在指定的地址分配内存并构建对象)
使用:Student *pstu = new(cpstu)(Student[3]);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值