簡體   English   中英

Memcpy unique_ptr 到向量

[英]Memcpy unique_ptr to vector

我正在嘗試將由unique_ptr 緩沖區uint32_t bufferSize描述的 memory 區域寫入std::vector value 當我為此使用 std::memcpy 時,我收到以下警告:

'void* memcpy(void*, const void*, size_t)' 寫入 'class std::vector<unsigned char, std::allocator >' 類型的 object,沒有簡單的復制分配; 改用復制分配或復制初始化 [-Wclass-memaccess]

int ReadByName (std::vector<unsigned char> &value, const char handleName[], std::ostream &out, const long &port, const AmsAddr &server)
{
        uint32_t bytesRead;

        out << __FUNCTION__ << "():  ";
        
        if (this->handle == 0)
            handle = getHandleByName(out, port, server, handleName);
        if (bufferSize == 0)
            bufferSize = getSymbolSize(out, port, server, handleName);

        const auto buffer = std::unique_ptr<uint8_t>(new uint8_t[bufferSize]);

        const long status = AdsSyncReadReqEx2(  port,
                                                &server,
                                                ADSIGRP_SYM_VALBYHND,
                                                handle,
                                                bufferSize,
                                                buffer.get(),
                                                &bytesRead);
        
        if (status) {
            out << "ADS read failed with: " << std::dec << status << '\n';
            return 2;
        }
        value.clear();
        value.reserve(bufferSize);
        std::memcpy(&value, buffer.get(), bufferSize);
        return 0;
}

解決問題的正確方法是什么?

問候蒂爾曼

解決問題的正確方法是什么?

這將是直接讀入向量,而不是稍后復制的單獨數組。

如果使用 AdsSyncReadReqEx2() 的讀取操作失敗,則值將已被清除。

不要清除value ,而是使用另一個向量。 如果操作成功,則將中間向量移動分配給不需要復制元素的value

更好的是:根本不要將value傳遞給 function,而是返回向量並使用比普通錯誤代碼更現代的錯誤處理機制。 您可以使用例如異常或類似於建議的std::expected的東西。

兩個錯誤,這里是正確的代碼

    value.clear();
    value.resize(bufferSize);
    std::memcpy(value.data(), buffer.get(), bufferSize);

第一個錯誤, &value沒有給你向量的數據區域供你寫入value.data()這樣做。

第二個錯誤, reserve不會改變向量的大小,所以你正在寫入一個空向量。 使用resize更改向量的大小。

編輯

很顯然,埃羅莉卡說的是真的。 您可以修改上述代碼,將指向矢量數據的有效指針傳遞給AdsSyncReadReqEx2並完全取消buffer

 value.resize(bufferSize);
 const long status = AdsSyncReadReqEx2(  port,
        &server,
        ADSIGRP_SYM_VALBYHND,
        handle,
        value.size(),
        value.data(),
        &bytesRead);

暫無
暫無

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

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