c ++ shared_ptr和memcpy错误[重复]

Posted

技术标签:

【中文标题】c ++ shared_ptr和memcpy错误[重复]【英文标题】:c++ shared_ptr & memcpy errors [duplicate] 【发布时间】:2017-11-14 19:38:23 【问题描述】:

我已决定转向现代 c++ 实践,并尝试调整我的旧代码以使用智能指针。我有一个包含数据包数据的数据包类,以及其他一些变量。

class Packet

public:
    Packet(int connId, std::shared_ptr<char[]> buff, size_t pLen) 
        : connID(connId), packetLen(pLen)
    
        buffer = buff;
    

    Packet()

    int connID;
    size_t packetLen;
    std::shared_ptr<char[]> buffer;
;

我有一个测试函数,可以创建数据并将其插入新分配的缓冲区。

std::vector<Packet> packetV;

void createPacket()

    std::shared_ptr<char[]> data = std::make_shared<char[]>(10);

    for (int i = 0; i < 5; ++i)
    
        uint8_t byte = 5;
        memcpy(*data.get() + i, &byte, sizeof(uint8_t));
    

    packetV.push_back(Packet(1, data, 5*sizeof(uint8_t)));


//(Main function)
void main()

    std::string input;
    do
    
        std::cin >> input;
        if (input == "packet") createPacket();
        else if (input == "exit") input.clear();
        else if (input == "empty") packetV.clear();
        else if (input == "show") std::cout << packetV.size() << std::endl;

     while (input.size() > 0);

当我尝试编译代码时,出现以下错误:

1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\type_traits(1192): error C2070: 'char []': illegal sizeof operand
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\type_traits(1199): note: see reference to class template instantiation 'std::aligned_union<1,_Ty>' being compiled
1>        with
1>        [
1>            _Ty=char []
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\memory(1731): note: see reference to alias template instantiation 'aligned_union_t<1,char[]>' being compiled
1>c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.11.25503\include\memory(1778): note: see reference to class template instantiation 'std::_Ref_count_obj<_Ty>' being compiled
1>        with
1>        [
1>            _Ty=char []
1>        ]
1>c:\users\...\documents\visual studio 2017\projects\..\...\source.cpp(29): note: see reference to function template instantiation 'std::shared_ptr<char []> std::make_shared<char[],int>(int &&)' being compiled

有人可以帮助我理解错误并建议我如何使用智能指针设计将数据插入和提取到 char * 数组中!?

【问题讨论】:

使用 std::vector 或 std::string! s/*data.get()/data.get() 由于其他评论没有为std::vector 提供任何动机,我认为主要的批评是当您使用std::shared_ptr 时,数据将如何共享并不明显。如果您确实想封装拥有数据,请使用std::unique_ptrstd::vector 另外你应该注意使用uint8_t可能是一个更适合用消息包来表示任意字节值的类型。 在转向现代 C++ 实践之前,您应该学习如何遵循旧的实践。例如数据封装和适当的成员初始化。 【参考方案1】:

std::shared_ptr 不是专门用于当前标准 C++ 版本中的数组。预计将在 C++20 中提供支持。

与此同时,您有几个选择:

使用std::string,它会自动管理动态大小的字符串,当有人说“在内存中保存一堆字符!”时,它确实应该是您的首选默认响应。 使用std::unique_ptr&lt;char[]&gt;。与 shared_ptr 不同,unique_ptr 专门用于数组,这意味着您尝试使用的构造将适用于它。 使用std::vector&lt;uint8_t&gt;。就其存储的数据而言,这(几乎)等同于 std::string,但这里的用法更加冗长:数据不仅仅是一串字符,具体而言,它是原始二进制数据。

【讨论】:

@tobi303 std::string 基于 signed char IIRC。 @tobi303 std::vector&lt;uint8_t&gt; 在分配数据时不隐式接受字符串文字,并且无符号值的未定义行为少于有符号值。如果您开始挑剔,charunsigned char在技术上不是相同的类型,即使它们的底层表示是相同的。 @tobi303 这是关于传达语义的。 std::string 说“这包含一个 String”,而 std::vector&lt;int8_t&gt;std::vector&lt;uint8_t&gt; 说“这包含 原始二进制数据。”。这种区别可以使您的代码的意图更加清晰,并减少错误的发生率。 语义方面我同意。我指的是“数据不仅仅是一串字符,而且具体来说,它是原始二进制数据”,在考虑了一段时间后,我想我只是误读了那句话(因为它不一定声称原始数据包含在字符串中的内容与包含在向量中的内容不同)。感谢您的耐心等待,我将删除旧的 cmets 我希望我会使用std::shared_ptr 节省一些内存,拥有一个将分发给所有客户端的数据包池。拥有std::unique_ptr 将迫使我为每个连接复制一份pacet。这就是为什么我希望std::share_ptr's 能救我。

以上是关于c ++ shared_ptr和memcpy错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

shared_ptr和动态数组

使用 gdb 查找 memcpy 错误

arm gcc5的交叉编译-正确使用memcpy

C语言 memcpy 函数

使用 gcc 编译器时未在此范围内声明“memcpy”

memcpy和strcpy的区别