簡體   English   中英

奇怪的C ++構造

[英]Weird c++ construct

我想為自己編譯openttd源。 它正在使用Squirell庫,由於鏈接器錯誤,我無法編譯該庫。 我查看了無法編譯的代碼,並且看到了我(和鏈接器:D)無法理解的怪異構造:

new ((void *)&_vals[i]) T(v._vals[i]);

整個源代碼(第41行)

我修改了代碼,現在看起來像這樣:

_vals[i] = *(new  T(v._vals[i]));

我不知道我是否以良好的方式修改了代碼。 我希望我做到了。 游戲現在還沒有崩潰,所以也許它運行良好。

有人可以說為什么這個構造沒有做任何編譯時錯誤,而只是鏈接器錯誤? 這段代碼到底在做什么?

重要信息:我正在使用Visual Studio 2013。

這是標准位置new 你可能失蹤了

#include <new>

您所做的修改已導致內存泄漏。 以前,新對象是使用new放置到已經分配的內存中的。 現在,您使用new創建一個對象,然后將其復制到_vals 但是,您永遠不會在原始文件上調用delete

這是新的位置

new (addr) T(...)

在內存地址addr處構造T對象。 在這里,它在地址&_vals[i]構造它,也就是說,它覆蓋了對象_vals[i] 該地址被強制轉換為void* ,即原始內存地址。

當對象是不可變的或未實現賦值運算符時,有時會用於重建對象。 例如

A a(1);
...
a.~A(); // needed as otherwise a would not get destructed
new (&a) A(2);
...

在與舊對象相同的地址處創建一個新的A對象,並使對該對象的引用和指針保持有效。

這是一個低級操作,可能會導致問題,即在不確定addr是否適合該對象時進行內存對齊。

修改后的代碼將在堆上構造一個新對象,並將其分配給現有對象,然后將其泄漏。 在這種情況下,這不會泄漏內存:

_vals[i] = T(v._vals[i]);

鏈接器錯誤可能是因為沒有T::operator=(const T&) ,並且由於使用了新的位置。 (例如,如果T包含引用成員並且是不可變的)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM