std::string 的数据内存是否连续?

norains 2008-06-02 10:16:08
对于std::vector来说,我们知道,内部存储的数据内存空间是连续的,因此代码如下是正确的:

std::vector<char> vtContent(MAX_NUMBER,0);
...
ReadFile(hFile,&vtContent[0],MAX_NUMBER,&dwRead);


那对于std::string来说,这样是否正确呢?
std::string stContent(MAX_NUMBER,0);
...
ReadFile(hFile,&stContent[0],MAX_NUMBER,&dwRead);

在C++编程规范中提到,std::string类型的存储内存是否连续需要根据不同的stl实现来定,但我觉得这个有点牵强。
我先说说自己的理由,
std::string可以用[]来获取数据,这个是C++标准规定的;如果用[]可以,那么应该也可以使用指针形式:
比如,char ch = stContent[5],
我们可以用指针:
char *pCont = reinterpret_cast<char *>(&stContent[0]);
char ch = *(pCont + 5);
如果可以用指针步进的话,那么内存应该是连续的才对。

当然,这个例子也有漏洞,如果说std::string内存不是连续也说得过去:
首先是std::string已经重载了[]操作符,用[]获取数据并不是根据内存连续来进行。指针可以用来指向数据,应该是不行的,例子的漏洞可能发生在转换中:reinterpret_cast<char *>。

想不明白,望大家指教~
...全文
1199 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
飞鸟真人 2021-06-16
  • 打赏
  • 举报
回复

具体是否连续,要看使用的STL版本的源码实现就知道了

MagiSu 2008-06-02
  • 打赏
  • 举报
回复
string似乎现在没有用引用计数了吧?
iambic 2008-06-02
  • 打赏
  • 举报
回复
s.c_str()是连续的。
&s[0]不一定是连续的。
norains 2008-06-02
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 mimong_lin 的回复:]
std::string可以用[]来获取数据,这个是C++标准规定的;如果用[]可以,那么应该也可以使用指针形式

能用[]来获取数据,可不表示“如果用[]可以,那么应该也可以使用指针形式”。[]只是一个运算符重载,它可以是经过重计算得到的,它的数据内容不一定就是连续的。
[/Quote]


可不表示“如果用[]可以,那么应该也可以使用指针形式”。
对这句话比较赞同。。。

因为C++编程规范中特意指出,只有vector才是内存连续的,其它的要看各家的STL实现。[]和指针不一定能互相转换
norains 2008-06-02
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 Supper_Jerry 的回复:]
数据是连续的,前面加了引用计数
[/Quote]

前面加了引用计数和数据连续似乎无关把?
norains 2008-06-02
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 phoenix3 的回复:]
应该是连续的,用string.c_str()得到的CHAR指针,能用STRSTR()等标准函数使用。
[/Quote]

string.c_str()是另外开辟的缓冲区,C++标准中没有规定.c_str()和string的存储缓冲相同,所以这个不足以作为证据
mimong_lin 2008-06-02
  • 打赏
  • 举报
回复
std::string可以用[]来获取数据,这个是C++标准规定的;如果用[]可以,那么应该也可以使用指针形式

能用[]来获取数据,可不表示“如果用[]可以,那么应该也可以使用指针形式”。[]只是一个运算符重载,它可以是经过重计算得到的,它的数据内容不一定就是连续的。
newkt 2008-06-02
  • 打赏
  • 举报
回复
连续
Supper_Jerry 2008-06-02
  • 打赏
  • 举报
回复
数据是连续的,前面加了引用计数
phoenix3 2008-06-02
  • 打赏
  • 举报
回复
应该是连续的,用string.c_str()得到的CHAR指针,能用STRSTR()等标准函数使用。
baihacker 2008-06-02
  • 打赏
  • 举报
回复
#include  <iostream>
#include <string>
#include <cstring>
using namespace std;

int main(int argc, char* argv[])
{
string s = "123";
cout << s.length() << endl << strlen(s.c_str()) << endl;
return 0;
}
taodm 2008-06-02
  • 打赏
  • 举报
回复
去查C++标准嘛。
iambic 2008-06-02
  • 打赏
  • 举报
回复
结贴吧。
myhuochai 2008-06-02
  • 打赏
  • 举报
回复
连续不连续,看标准啊,我查了iso14882 标准,里面没有要求 string 一定要使用连续存储空间。所以有的实现可能使用连续存储,有的不使用,就是这样。不怕死的当然也可以假设所有的实现都是使用连续存储的…

lionc650 2008-06-02
  • 打赏
  • 举报
回复
学习~~
leelittlelong 2008-06-02
  • 打赏
  • 举报
回复
刚看了看vc7的sdk中的string
肯定是连续的。
_Elem _Buf[_BUF_SIZE];
_Elem *_Ptr;
norains 2008-06-02
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 codeangel 的回复:]
应该是连接的。
C/C++ code
string str(_T("abc"));

printf("%s-%s-%s",str[0],str[1],str[2]);
[/Quote]

这个依然无法证明是否连续,
因为在实现中很可能这样:
(打个比方)
存储数据<1M ,空间连续
存储数据>=1M ,空间不连续,
实现以1M为一block实现的话。
jieao111 2008-06-02
  • 打赏
  • 举报
回复
看看分配的地址
norains 2008-06-02
  • 打赏
  • 举报
回复
实际情况应该是这样:

C++标准中没有规定string中是连续的。

VS2005的STL中经过测试,1m的空间是连续的。。。
norains 2008-06-02
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 k2eats 的回复:]
C/C++ code
#include <iostream>
#include <string>
#include <cstring>
using namespace std;

int main(int argc, char* argv[])
{
string s = "12343sdd";
cout << sizeof(s) << endl << sizeof("12343sdd")<< endl;
system("pause");
return 0;
}


结果是16和9(VC)
string应该是不连续,包含字节补全到16字节!
[/Quote]

这个检验是错的。因为string是类模板,所以s为类对象,而该对象包含存储字符串(例子为"12343sdd")的空间以及一些杂七杂八的东西,所以sizeof(s)!= sizeof("12343sdd")
加载更多回复(5)

64,642

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧