简体   繁体   English

让`std :: vector <unsigned char> `从`std :: string`窃取内存

[英]Letting a `std::vector<unsigned char>` steal memory from a `std::string`

Suppose we have std::string s holding a raw data buffer, but we want std::vector<uint8_t> v instead. 假设我们有std::string s持有原始数据缓冲区,但我们想要std::vector<uint8_t> v代替。 The buffer length is in the millions. 缓冲区长度以百万计。 Is there a simple way to let v steal s 's memory and thereby avoid copying the buffer? 有没有一种简单的方法可以让v窃取s的内存,从而避免复制缓冲区?

Like what std::vector<uint8_t>::vector(std::string&&) would have done, but doing it somehow from the outside of STL. 就像std::vector<uint8_t>::vector(std::string&&)那样,但是从STL的外部以某种方式进行。

Alternatively, is it possible to get v from std::stringstream ss with an operation about as efficient as ss.str() ? 或者,是否可以通过与ss.str()一样有效的操作从std::stringstream ss获取v

OK, lots of comments there, let's try and put something together, because I need the practise and might maybe earn some points [update: didn't :(]. 好,那里有很多评论,让我们尝试将它们放在一起,因为我需要练习,并且可能会获得一些积分[更新:没有:(]。

I'm fairly new to 'modern C++' so please take it as you find it. 我对“现代C ++”还不陌生,因此请随便使用。 Might need as late as C++17, I haven't checked that too carefully. 可能需要迟到C ++ 17,我还没有仔细检查过。 Any critique more than welcome but I would prefer to edit my own post. 任何批评都值得欢迎,但我希望编辑自己的帖子。 And please bear in mind when reading this that what the OP actually wants to do is read his bytes from a file. 并且在阅读本文时请记住,OP 实际要执行的操作是从文件中读取其字节。 Thx. 谢谢。

Update: Tweaked to handle the case where the the file size changes between the call to stat() and the call to fread() as per @Deduplicator's comment below ... and subsequently replaced fread with std::ifstream , I think we're there now. 更新:调整以处理以下情况,即文件大小根据下面@Deduplicator的注释在stat()调用与fread()调用之间改变...然后将fread替换为std::ifstream ,我认为现在在那里。

#include <string>
#include <vector>
#include <optional>
#include <iostream>
#include <fstream>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>

using optional_vector_of_char = std::optional <std::vector <char>>;

// Read file into a std::optional <std::vector <char>>.
// Now handles the file size changing when we're not looking.
optional_vector_of_char SmarterReadFileIntoVector (std::string filename)
{
    for ( ; ; )
    {
        struct stat stat_buf;
        int err = stat (filename.c_str (), &stat_buf);
        if (err)
        {
            // handle the error
            return optional_vector_of_char ();   // or maybe throw an exception
        }

        size_t filesize = stat_buf.st_size;

        std::ifstream fs;
        fs.open (filename, std::ios_base::in | std::ios_base::binary);
        if (!fs.is_open ())
        {
            // handle the error
            return optional_vector_of_char ();
        }

        optional_vector_of_char v (filesize + 1);
        std::vector <char>& vecref = v.value ();
        fs.read (vecref.data (), filesize + 1);

        if (fs.rdstate () & std::ifstream::failbit)
        {
            // handle the error
            return optional_vector_of_char ();
        }

        size_t bytes_read = fs.gcount ();
        if (bytes_read <= filesize)              // file same size or shrunk, this code handles both
        {
            vecref.resize (bytes_read);
            vecref.shrink_to_fit ();
            return v;                            // RVO
        }

        // File has grown, go round again
    }
}    

int main ()
{
    optional_vector_of_char v = SmarterReadFileIntoVector ("abcde");
    std::cout << std::boolalpha << v.has_value () << std::endl;
}

Live demo . 现场演示 No actual file available to read in of course, so... 当然没有可用的实际文件可供读取,因此...


Also : Have you considered writing your own simple container that maps a view of the file? 另外 :您是否考虑过编写自己的简单容器来映射文件视图? Just a thought. 只是一个想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从 std::vector 初始化 std::string<unsigned char> 导致错误 - Initialization of std::string from std::vector<unsigned char> causes error std ::在std :: string和std :: vector之间移动<unsigned char> - std::move between std::string and std::vector<unsigned char> 将对象的 std::vector 从/转换为 unsigned char 的 std::vector - convert a std::vector of objects from/to a std::vector of unsigned char 如何将具有十六进制值的 std::string 转换为 std::vector<unsigned char></unsigned> - How to convert std::string with hex values into std::vector<unsigned char> 饲料 std::vector<unsigned char> 来自无符号字符 * - Feed std::vector<unsigned char> from unsigned char * unsigned char std :: vector to unsigned char []? - Unsigned char std::vector to unsigned char[]? 的std ::矢量 <unsigned char> 到QPixmap - std::vector<unsigned char> to QPixmap 如何为const std :: vector释放内存<unsigned char> - How to deallocate memory for const std::vector<unsigned char> 转换C ++ std :: vector <std::string> 到std :: vector <unsigned char> (反之亦然) - converting a c++ std::vector<std::string> to std::vector<unsigned char> (and vice versa) std :: vector &lt;std :: vector <unsigned char> &gt;或std :: deque &lt;std :: vector <unsigned char> &gt;? - std::vector< std::vector<unsigned char> > or std::deque< std::vector<unsigned char> >?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM