C++ 将char*分配给字符串而不复制
这是一个相当简单的问题,但我发现它很棘手。我想将C++ 将char*分配给字符串而不复制,c++,arrays,string,copy,C++,Arrays,String,Copy,这是一个相当简单的问题,但我发现它很棘手。我想将char*视为std::string,例如: char *p = ...; // read a huge chuck from a file std::string s(p); // this is not what I want 因此,如果我使用构造函数,我会得到一个p的副本,这是对内存和时间的浪费。是否有可能以某种方式避免这种情况,并将std::string内容“分配”到预先存在的地址 任何其他想法都是非常受欢迎的 谢谢 是
char*
视为std::string
,例如:
char *p = ...; // read a huge chuck from a file
std::string s(p); // this is not what I want
因此,如果我使用构造函数,我会得到一个p的副本,这是对内存和时间的浪费。是否有可能以某种方式避免这种情况,并将std::string
内容“分配”到预先存在的地址
任何其他想法都是非常受欢迎的
谢谢
是否有可能以某种方式避免这种情况,并将std::string
内容“分配”到预先存在的地址
没有
但是,您可以将其指定给。接下来,除了拥有内存之外,所有使用
std::string
的方法都应该被std::string\u视图
替换,为什么不使用std::vector
?例如:
std::vector<char> data;
data.resize( size ); // resize this to how much you need
char* p = &data[0];
// now you have a pointer to the internal data in std::vector
std::矢量数据;
数据。调整大小(大小);//将此大小调整为您需要的大小
char*p=&数据[0];
//现在您有了一个指向std::vector中内部数据的指针
std::string
不支持也不可能支持此功能,因为它拥有字符串缓冲区
这意味着它最终必须释放内存,或者在您更改字符串的长度时重新分配内存。如果不是更早,则必须在程序退出时执行此操作
现在,
string
应该如何处理它通过指针获得的未知内存块?这个内存是在堆或堆栈上分配的,还是来自数据段的只读内存?没有任何string
可以做的事情是有效的,并且在一种或另一种情况下不会泄漏或导致崩溃。没有,因为std::string
通常期望的比char*
能够提供的更多,最显著的是将存储重新分配到完全不同的内存位置。另外,std::string
不保证以null结尾,它只提供了一个begin()
和一个end()
但请注意,std::string
和char[]
具有非常常见的接口:
- 您可以使用数字对它们进行索引,并获得
字符
- 您可以调用它们的
和std::begin
,并获得随机访问迭代器,这样像std::end
这样的算法就可以对它们自由操作sort
这是C++标准模板库的核心——容器和算法是分开的,相同的算法可以在
当然
不是char*
,但是一对char[]
s看起来就像char*
和begin(char[])
,这样,您就可以将它连接到在随机访问迭代器方面工作的STL实用程序。end(char[])
std::string
实现没有实现这样的功能。甚至使用,因为内部成员可以从一个实现更改到另一个实现,或者从一个版本更改到另一个版本,或者根据一些#define
。。。您还可以选择提供自己的std::string
分配器,但这似乎不是处理此类问题的方法
是一些字符串
实现允许将缓冲区重用为缓冲区
这个想法已经在其他一些问题/答案中得到了处理:
此外,还有一个as-for被…使用,为什么不直接将文件中的大块读取到
std::string
中呢?这听起来像是XY问题。您希望对数据执行什么样的操作,使其成为字符串
?数据已经存在于内存中,例如内存映射文件。这就是为什么我不能有一个std::string
。@JonathanLeffler:std::string是一个对象,它需要的不仅仅是字符*,所以你只能直接复制它td::string\u视图是你想要的。这似乎与OP想要的相反。是的,我同意@KonradRudolph,我希望数据指向p,其中p是指向已分配数据的指针。因此,既然std::string
不能这样做,那么std::vector
是可行的选项吗?当然,我需要编写一些附加函数,但如果速度更快(不复制),我会这样做。vector
也是如此,所以没有。vector分配、重新分配、拥有并最终释放存储。因此,它也必须将char*
缓冲区中的数据复制到自己的存储区中,没有其他方法。如果您不知道缓冲区是如何分配的,或者缓冲区是否可以释放,那么就不可能拥有或释放(或重新分配)缓冲区。调用allocator::deallocate
或operator delete
(或free
,这通常是底层机制)处理未以相同方式分配的内容几乎肯定会导致崩溃(释放NULL是唯一值得注意的例外)。谢谢,这就澄清了我的疑问。为什么我们不能反过来做呢?也就是说,如果我预先知道要从文件中读取的字符串的长度,也许我可以将该字符串调整为该值(以确保它在内部分配了适当的内存量),然后以某种方式要求该字符串提供指向其内部缓冲区的指针,以便直接将数据读入其中?Inb4称之为“不安全”之类的:它并不比逐字节读取这些数据并在循环中使用[]运算符分配给字符串更安全(只是不那么麻烦)。