Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 将char*分配给字符串而不复制_C++_Arrays_String_Copy - Fatal编程技术网

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++标准模板库的核心——容器和算法是分开的,相同的算法可以在 STD::String 和 char []/Cuff>


当然
char*
不是
char[]
,但是一对
char*
s看起来就像
begin(char[])
end(char[])
,这样,您就可以将它连接到在随机访问迭代器方面工作的STL实用程序。

广泛的
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称之为“不安全”之类的:它并不比逐字节读取这些数据并在循环中使用[]运算符分配给字符串更安全(只是不那么麻烦)。