placement new[]是有毒的

ID870177103 2017-10-07 12:39:31
对于non-pod类型返回的地址不一样 https://stackoverflow.com/questions/21441245/operator-new-and-non-pod-types
...全文
860 18 打赏 收藏 转发到动态 举报
写回复
用AI写文章
18 条回复
切换为时间正序
请发表友善的回复…
发表回复
xskxzr 2017-10-15
  • 打赏
  • 举报
回复
引用 12 楼 ID870177103 的回复:
[quote=引用 8 楼 xsklld 的回复:] [quote=引用 7 楼 ID870177103 的回复:] [quote=引用 6 楼 xsklld 的回复:] [quote=引用 2 楼 ID870177103 的回复:] [quote=引用 1 楼 xsklld的回复:]跟placement new有什么关系?
简单来说就是 memory_pool mp ; auto a = mp.alloc (3 * sizeof (int)) ; auto b = new (&a) int[3] ; assert (a == b) ; 这段代码没毛病 不过把int换成non-pod类型 断言就是失败[/quote] 为啥要assert a==b呢?[/quote] 兄弟,你把int换成std::string,然后去掉assert,开debug跑一下,你就会发现问题了[/quote] 我是说为啥要强行让a等于b?[/quote] [/quote] 你把tmp申请大一点不就好了?
ID870177103 2017-10-12
  • 打赏
  • 举报
回复
引用 13 楼 D41D8CD98F的回复:
placement new[] 确实是有毒的 不过如果是遵守 Itanium ABI 的编译器,比如 GCC,就不会出问题 https://itanium-cxx-abi.github.io/cxx-abi/abi.html#array-cookies: No cookie is required if the new operator being used is ::operator new[](size_t, void*).
确实,我用g++4.8没有问题 而且在地址对齐方面g++也和vs有区别
ID870177103 2017-10-12
  • 打赏
  • 举报
回复
引用 15 楼 codedoctor的回复:
而且,的确如你所说,placement new[]是存在很大的问题的,所以你想用的话,最好还是挨个的用placement new 去构造对象,然后用对象指针进行管理,这样不仅方便构造,也方便析构
额,现在就是用的这个 我函数里面加scope guard,来防止异常 然后看起来怪怪的
codedoctor 2017-10-11
  • 打赏
  • 举报
回复
而且,的确如你所说,placement new[]是存在很大的问题的,所以你想用的话,最好还是挨个的用placement new 去构造对象,然后用对象指针进行管理,这样不仅方便构造,也方便析构
D41D8CD98F 2017-10-11
  • 打赏
  • 举报
回复
placement new[] 确实是有毒的 不过如果是遵守 Itanium ABI 的编译器,比如 GCC,就不会出问题 https://itanium-cxx-abi.github.io/cxx-abi/abi.html#array-cookies: No cookie is required if the new operator being used is ::operator new[](size_t, void*).
codedoctor 2017-10-11
  • 打赏
  • 举报
回复
引用 11 楼 ID870177103 的回复:
[quote=引用 10 楼 codedoctor 的回复:] 你那样会导致内存溢出。
是的,而且在x64上要留8byte,我想要问的是这个是标准吗?还是说编译器执行的规范[/quote] 编译器的规范,不同的编译器实现的方式有所不同。
ID870177103 2017-10-11
  • 打赏
  • 举报
回复
引用 8 楼 xsklld 的回复:
[quote=引用 7 楼 ID870177103 的回复:] [quote=引用 6 楼 xsklld 的回复:] [quote=引用 2 楼 ID870177103 的回复:] [quote=引用 1 楼 xsklld的回复:]跟placement new有什么关系?
简单来说就是 memory_pool mp ; auto a = mp.alloc (3 * sizeof (int)) ; auto b = new (&a) int[3] ; assert (a == b) ; 这段代码没毛病 不过把int换成non-pod类型 断言就是失败[/quote] 为啥要assert a==b呢?[/quote] 兄弟,你把int换成std::string,然后去掉assert,开debug跑一下,你就会发现问题了[/quote] 我是说为啥要强行让a等于b?[/quote]
ID870177103 2017-10-11
  • 打赏
  • 举报
回复
引用 10 楼 codedoctor 的回复:
你那样会导致内存溢出。
是的,而且在x64上要留8byte,我想要问的是这个是标准吗?还是说编译器执行的规范
codedoctor 2017-10-11
  • 打赏
  • 举报
回复
你那样会导致内存溢出。
codedoctor 2017-10-11
  • 打赏
  • 举报
回复
兄弟,这个问题,非常简单。 因为对于含有显式的构造和析构函数的对象来说,编译器会在placement new的时候在对象数组前面放入一个int类型大小的数字标识有当前正有多少个对象被构建,以便于后面能够完整的析构,测试代码如下:
//测试
class A {
public:
	A() { };
	~A() {};
};

int main() 
{
	auto a = malloc(4 * sizeof(A));
	auto b = new (a) A[4];
	cout << (int)a << endl;
	cout << (int)b << endl;
	cout << *(((int*)b)-1) << endl;
	system("pause"); 
	return 0;
}
输出如下:
15764912
15764916
4
所以你应该多分配四个字节,OVER 具体可以看我的博客【C++】 深入探究 new 和 delete
xskxzr 2017-10-09
  • 打赏
  • 举报
回复
引用 2 楼 ID870177103 的回复:
[quote=引用 1 楼 xsklld的回复:]跟placement new有什么关系?
简单来说就是 memory_pool mp ; auto a = mp.alloc (3 * sizeof (int)) ; auto b = new (&a) int[3] ; assert (a == b) ; 这段代码没毛病 不过把int换成non-pod类型 断言就是失败[/quote] 为啥要assert a==b呢?
xskxzr 2017-10-09
  • 打赏
  • 举报
回复
引用 7 楼 ID870177103 的回复:
[quote=引用 6 楼 xsklld 的回复:] [quote=引用 2 楼 ID870177103 的回复:] [quote=引用 1 楼 xsklld的回复:]跟placement new有什么关系?
简单来说就是 memory_pool mp ; auto a = mp.alloc (3 * sizeof (int)) ; auto b = new (&a) int[3] ; assert (a == b) ; 这段代码没毛病 不过把int换成non-pod类型 断言就是失败[/quote] 为啥要assert a==b呢?[/quote] 兄弟,你把int换成std::string,然后去掉assert,开debug跑一下,你就会发现问题了[/quote] 我是说为啥要强行让a等于b?
ID870177103 2017-10-09
  • 打赏
  • 举报
回复
引用 6 楼 xsklld 的回复:
[quote=引用 2 楼 ID870177103 的回复:] [quote=引用 1 楼 xsklld的回复:]跟placement new有什么关系?
简单来说就是 memory_pool mp ; auto a = mp.alloc (3 * sizeof (int)) ; auto b = new (&a) int[3] ; assert (a == b) ; 这段代码没毛病 不过把int换成non-pod类型 断言就是失败[/quote] 为啥要assert a==b呢?[/quote] 兄弟,你把int换成std::string,然后去掉assert,开debug跑一下,你就会发现问题了
真相重于对错 2017-10-08
  • 打赏
  • 举报
回复
一下来源自网络----- 传递给“placement new”操作符的指针所指向的内存区域必须足够大,并且可能需要为所创建的对象进行边界调整。编译器和运行时系统都不会进行任何的尝试来检查你做的是否正确。如果 类需要将边界调整为4字节,而你提供的位置没有进行边界调整的话,你就会亲手制造一个严重的灾难(如果你不明白“边界调整”的意思,那么就不要使用placement new语法)。
ID870177103 2017-10-08
  • 打赏
  • 举报
回复
引用 4 楼 倦怠的回复:
一下来源自网络----- 传递给“placement new”操作符的指针所指向的内存区域必须足够大,并且可能需要为所创建的对象进行边界调整。编译器和运行时系统都不会进行任何的尝试来检查你做的是否正确。如果 类需要将边界调整为4字节,而你提供的位置没有进行边界调整的话,你就会亲手制造一个严重的灾难(如果你不明白“边界调整”的意思,那么就不要使用placement new语法)。
哦,学到了 虽然和placement new[]的问题不是一个原因 placement new[]保留了一个机器字的地址 应该是 用于有一次构造函数发生异常时 确认哪些类已经完成构造 但是如果确实想要明确阻止编译器对placement new进行进行对齐 我应该怎么做 虽然我现在使用 new (this) T 或者 char data[sizeof(T)] new (&data) T 还没遇到过问题
ID870177103 2017-10-07
  • 打赏
  • 举报
回复
上面打错字是new (a) int[3] ; a就是指针
ID870177103 2017-10-07
  • 打赏
  • 举报
回复
引用 1 楼 xsklld的回复:
跟placement new有什么关系?
简单来说就是 memory_pool mp ; auto a = mp.alloc (3 * sizeof (int)) ; auto b = new (&a) int[3] ; assert (a == b) ; 这段代码没毛病 不过把int换成non-pod类型 断言就是失败
xskxzr 2017-10-07
  • 打赏
  • 举报
回复
跟placement new有什么关系?
内容概要:本文围绕“计及V2G主动支撑的光伏-储能-电动汽车输配协同日前优化调度”展开研究,提出了一种综合考虑光伏发电、储能系统与电动汽车(EV)在V2G(Vehicle-to-Grid)模式下协同参与电网调度的优化模型。通过Matlab代码实现,构建了日前优化调度框架,充分挖掘电动汽车作为移动储能单元的潜力,利用其双向充放电能力为主动配电网提供调峰、填谷和备用等主动支撑服务。研究综合考虑了可再生能源出力不确定性、负荷需求波动以及电动汽车出行行为特征,建立了多主体、多目标的协同优化机制,旨在降低系统运行成本、提高新能源消纳水平,并增强电网运行的稳定性与可靠性。该资源属于电力系统与综合能源系统领域的高水平科研复现资料,具备较强的理论深度与工程应用价值; 适合人群:具备电力系统分析、优化建模基础及Matlab编程能力的研究生、科研人员,以及从事智能电网、能源互联网、综合能源系统等相关领域技术研发的专业技术人员; 使用场景及目标:①用于学习和复现源-网-荷-储协同优化调度的核心建模方法与求解流程;②掌握V2G技术在电网调频调峰中的数学建模方法及其在优化调度中的集成应用;③支撑光伏、储能与电动汽车耦合系统的低碳经济调度、鲁棒优化或分布鲁棒优化等前沿课题的研究与仿真验证; 阅读建议:建议结合文中提供的Matlab代码与主流优化工具箱(如YALMIP、CPLEX、Gurobi等)进行实践操作,重点理解目标函数设计、约束条件构建及多变量耦合关系的处理策略,同时可进一步拓展至日内滚动优化、实时调度或多时间尺度协调优化方向开展深入研究。
内容概要:本文提出了一种基于改进自适应完备集合经验模态分解(Improved Adaptive Complete Ensemble Empirical Mode Decomposition, ICEEMDAN)的混合储能辅助火电机组调频协同控制策略,并提供了完整的Matlab代码实现。该策略利用ICEEMDAN对电网频率波动信号进行高精度自适应分解,提取不同时间尺度下的功率分量,进而合理分配火电机组与混合储能系统(如蓄电池、飞轮等)的调频任务,充分发挥各自响应速度快慢互补的优势。通过引入优化算法对功率分配系数进行动态整定,实现了调频过程中储能系统的高效协同运行,有效抑制了功率波动,提升了系统频率调节的快速性、稳定性和调节精度,同时延长了储能设备的使用寿命。文中详细阐述了算法原理、模型构建、控制逻辑设计及仿真验证过程,具有较强的可复现性与工程应用价值。; 适合人群:具备电力系统自动化、新能源并网控制或智能优化算法等相关专业知识背景,熟悉Matlab/Simulink仿真平台的技术人员,特别适用于从事电网调频、储能系统控制、信号处理在电力系统中应用等方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①深入研究混合储能系统在提升传统火电机组调频性能中的作用机制;②掌握ICEEMDAN等先进非平稳信号处理方法在功率动态分解中的具体实现与参数调优;③构建火电机组-储能协同调频仿真模型,开展多工况对比分析以优化控制性能;④为相关学术论文复现、科研项目申报或实际工程方案设计提供可靠的技术参考与代码支持。; 阅读建议:建议结合Matlab代码逐模块阅读文档内容,重点关注ICEEMDAN的实现流程、IMF分量筛选规则、功率分配权重计算逻辑及整体控制架构的设计思路。读者可通过调整信号噪声水平、滤波参数、储能容量配置等变量进行仿真实验,对比不同策略下的调频效果,从而深化对协同控制机理的理解,并可进一步拓展至风光火储联合系统或多时间尺度协调控制的研究场景。

65,210

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧