第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

使用memcpy“構(gòu)造”一個(gè)??平凡可復(fù)制的對(duì)象

使用memcpy“構(gòu)造”一個(gè)??平凡可復(fù)制的對(duì)象

C++
蕪湖不蕪 2019-11-19 15:25:55
在C ++中,此代碼正確嗎?#include <cstdlib>#include <cstring>struct T   // trivially copyable type{    int x, y;};int main(){    void *buf = std::malloc( sizeof(T) );    if ( !buf ) return 0;    T a{};    std::memcpy(buf, &a, sizeof a);    T *b = static_cast<T *>(buf);    b->x = b->y;    free(buf);}換句話說,是否是*b一個(gè)壽命已經(jīng)開始的物體?(如果是這樣,它什么時(shí)候開始的?)
查看完整描述

3 回答

?
滄海一幻覺

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超5個(gè)贊

    n3751支持以下未指定的操作:對(duì)象生存期,低級(jí)編程和memcpy,其中包括:


C ++標(biāo)準(zhǔn)目前對(duì)使用memcpy復(fù)制對(duì)象表示字節(jié)在概念上是賦值還是對(duì)象構(gòu)造都保持沉默。對(duì)于基于語義的程序分析和轉(zhuǎn)換工具以及跟蹤對(duì)象生存期的優(yōu)化程序,差異確實(shí)很重要。本文建議


允許使用memcpy復(fù)制兩個(gè)不同的平凡可復(fù)制表(但是大小相同)的兩個(gè)不同對(duì)象的字節(jié)


這樣的使用被識(shí)別為初始化,或更普遍地被識(shí)別為(概念上)對(duì)象構(gòu)造。


識(shí)別為對(duì)象構(gòu)造將支持二進(jìn)制IO,同時(shí)仍允許基于生命周期的分析和優(yōu)化器。


我找不到本文討論過的任何會(huì)議紀(jì)要,因此似乎仍然是一個(gè)未解決的問題。


C ++ 14草案標(biāo)準(zhǔn)目前在1.8 [intro.object]中說:


[...]在需要時(shí),通過定義(3.1),新表達(dá)式(5.3.4)或?qū)崿F(xiàn)(12.2)創(chuàng)建對(duì)象。[...]


這是我們所沒有的malloc,而復(fù)制瑣碎可復(fù)制類型的標(biāo)準(zhǔn)中所涉及的情況似乎僅引用3.9 [basic.types]部分中已存在的對(duì)象:


對(duì)于任何普通可復(fù)制類型T的對(duì)象(基類子對(duì)象除外),無論該對(duì)象是否持有類型T的有效值,組成該對(duì)象的基礎(chǔ)字節(jié)(1.7)都可以復(fù)制到char或unsigned char.42如果將char或unsigned char數(shù)組的內(nèi)容復(fù)制回該對(duì)象,則該對(duì)象隨后應(yīng)保留其原始值[...]


和:


對(duì)于任何普通可復(fù)制類型T,如果兩個(gè)指向T的指針指向不同的T對(duì)象obj1和obj2,則將組成obj1的基礎(chǔ)字節(jié)(1.7)復(fù)制到obj2,43 obj2,其中obj1和obj2都不是基類子對(duì)象。隨后應(yīng)保持與obj1相同的值。[...]


提案基本上是這樣說的,因此這不足為奇。


dyp從ub郵件列表中指出了關(guān)于該主題的有趣討論:[ub]鍵入punning以避免復(fù)制。


投標(biāo)p0593:隱式創(chuàng)建對(duì)象以進(jìn)行低級(jí)對(duì)象操作

提案p0593試圖解決此問題,但AFAIK尚未得到審查。


本文建議在新分配的存儲(chǔ)中根據(jù)需要按需創(chuàng)建足夠瑣碎類型的對(duì)象,以賦予程序定義的行為。


它有一些激勵(lì)性的示例,它們?cè)诒举|(zhì)上相似,包括當(dāng)前的std :: vector實(shí)現(xiàn),該實(shí)現(xiàn)當(dāng)前具有未定義的行為。


它提出了以下幾種隱式創(chuàng)建對(duì)象的方法:


我們建議至少將以下操作指定為隱式創(chuàng)建對(duì)象:


char,unsigned char或std :: byte數(shù)組的創(chuàng)建在該數(shù)組中隱式創(chuàng)建對(duì)象。


對(duì)malloc,calloc,realloc或任何名為operator new或operator new []的函數(shù)的調(diào)用會(huì)在其返回的存儲(chǔ)中隱式創(chuàng)建對(duì)象。


std :: allocator ::: allocate同樣在返回的存儲(chǔ)中隱式創(chuàng)建對(duì)象;分配器要求應(yīng)該要求其他分配器實(shí)現(xiàn)也要這樣做。


調(diào)用memmove的行為就像


將源存儲(chǔ)復(fù)制到臨時(shí)區(qū)域


在目標(biāo)存儲(chǔ)中隱式創(chuàng)建對(duì)象,然后


將臨時(shí)存儲(chǔ)復(fù)制到目標(biāo)存儲(chǔ)。


這允許記憶保留普通復(fù)制對(duì)象的類型,或用于將一個(gè)對(duì)象的字節(jié)表示重新解釋為另一對(duì)象的字節(jié)表示。


調(diào)用memcpy的行為與調(diào)用memmove的行為相同,不同之處在于它在源和目標(biāo)之間引入了重疊限制。


提名聯(lián)合成員的類成員訪問將觸發(fā)由聯(lián)合成員占用的存儲(chǔ)區(qū)中的隱式對(duì)象創(chuàng)建。請(qǐng)注意,這不是一個(gè)全新的規(guī)則:[P0137R1]中已經(jīng)存在此權(quán)限,其中成員訪問位于分配的左側(cè),但現(xiàn)在已被概括為該新框架的一部分。如下所述,這不允許通過聯(lián)合進(jìn)行類型修剪。相反,它僅允許通過類成員訪問表達(dá)式來更改活動(dòng)的聯(lián)合成員。


應(yīng)將新的屏障操作(不同于不會(huì)創(chuàng)建對(duì)象的std :: launder)引入標(biāo)準(zhǔn)庫,其語義等效于具有相同源存儲(chǔ)和目標(biāo)存儲(chǔ)的內(nèi)存。作為一名稻草人,我們建議:


// Requires: [start, (char*)start + length) denotes a region of allocated

// storage that is a subset of the region of storage reachable through start.

// Effects: implicitly creates objects within the denoted region.

void std::bless(void *start, size_t length);

除上述內(nèi)容外,還應(yīng)將實(shí)現(xiàn)標(biāo)準(zhǔn)定義的非標(biāo)準(zhǔn)內(nèi)存分配和映射功能集(例如POSIX系統(tǒng)上的mmap和Windows系統(tǒng)上的VirtualAlloc)指定為隱式創(chuàng)建對(duì)象。


注意,指針reinterpret_cast不足以觸發(fā)隱式對(duì)象創(chuàng)建。


查看完整回答
反對(duì) 回復(fù) 2019-11-19
?
慕村9548890

TA貢獻(xiàn)1884條經(jīng)驗(yàn) 獲得超4個(gè)贊

此代碼正確嗎?


好吧,它通常會(huì)“起作用”,但僅適用于瑣碎的類型。


我知道您沒有要求它,但是讓我們使用一個(gè)非平凡類型的示例:


#include <cstdlib>

#include <cstring>

#include <string>


struct T   // trivially copyable type

{

    std::string x, y;

};


int main()

{

    void *buf = std::malloc( sizeof(T) );

    if ( !buf ) return 0;


    T a{};

    a.x = "test";


    std::memcpy(buf, &a, sizeof a);    

    T *b = static_cast<T *>(buf);


    b->x = b->y;


    free(buf);

}

構(gòu)造后a,a.x將分配一個(gè)值。假設(shè)std::string未針對(duì)使用較小字符串值的本地緩沖區(qū)進(jìn)行優(yōu)化,而只是將數(shù)據(jù)指針指向外部存儲(chǔ)塊。將原樣memcpy()的內(nèi)部數(shù)據(jù)復(fù)制a到中buf?,F(xiàn)在a.x,b->x為string數(shù)據(jù)引用相同的內(nèi)存地址。當(dāng)b->x分配一個(gè)新值時(shí),該存儲(chǔ)塊將被釋放,但a.x仍會(huì)引用它。當(dāng)a隨后在年底進(jìn)入的范圍了main(),它會(huì)嘗試再次釋放相同的內(nèi)存塊。發(fā)生未定義的行為。


如果要“正確”,將對(duì)象構(gòu)造到現(xiàn)有內(nèi)存塊中的正確方法是改用placement-new運(yùn)算符,例如:


#include <cstdlib>

#include <cstring>


struct T   // does not have to be trivially copyable

{

    // any members

};


int main()

{

    void *buf = std::malloc( sizeof(T) );

    if ( !buf ) return 0;


    T *b = new(buf) T; // <- placement-new

    // calls the T() constructor, which in turn calls

    // all member constructors...


    // b is a valid self-contained object,

    // use as needed...


    b->~T(); // <-- no placement-delete, must call the destructor explicitly

    free(buf);

}


查看完整回答
反對(duì) 回復(fù) 2019-11-19
  • 3 回答
  • 0 關(guān)注
  • 664 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)