std::字符串和新位置 我发现了这个例子,在C++中使用新的布局,对我来说没有意义。 我认为这段代码很容易出现异常,因为可能会使用比分配的内存更多的内存 char *buf = new char[sizeof(string)]; string *p = new (buf) string("hi"); 如果“String”是C++ STD::String类,那么BUF将得到分配 空字符串对象的大小(我的编译器提供28字节), 我认为如果你用更多的字符初始化你的字符串 超出分配的内存。例如: string *p = new (buf) string("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");

std::字符串和新位置 我发现了这个例子,在C++中使用新的布局,对我来说没有意义。 我认为这段代码很容易出现异常,因为可能会使用比分配的内存更多的内存 char *buf = new char[sizeof(string)]; string *p = new (buf) string("hi"); 如果“String”是C++ STD::String类,那么BUF将得到分配 空字符串对象的大小(我的编译器提供28字节), 我认为如果你用更多的字符初始化你的字符串 超出分配的内存。例如: string *p = new (buf) string("hiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii");,c++,string,placement-new,C++,String,Placement New,在我的VS上,这似乎仍然有效,我不确定这是否是因为 这个异常不知何故被放弃了,或者我根本不明白字符串是如何工作的 有人能帮我澄清一下吗?sizeof返回的大小是存储类成员所需的字节数,其中有一些实现定义的填充。必须先分配内存,然后才能调用std::string的构造函数 但是,当构造函数运行时,它可能会分配更大的内存量,为了存储大字符串,它确实必须分配更大的内存量。该内存量不是大小的一部分,您不需要自己分配它。您误解了std::string的(典型)内部实现。通常它是这样实现的: class s

在我的VS上,这似乎仍然有效,我不确定这是否是因为 这个异常不知何故被放弃了,或者我根本不明白字符串是如何工作的


有人能帮我澄清一下吗?

sizeof返回的大小是存储类成员所需的字节数,其中有一些实现定义的填充。必须先分配内存,然后才能调用
std::string
的构造函数


但是,当构造函数运行时,它可能会分配更大的内存量,为了存储大字符串,它确实必须分配更大的内存量。该内存量不是
大小的一部分,您不需要自己分配它。

您误解了std::string的(典型)内部实现。通常它是这样实现的:

class string {
protected:
    char *buffer;
    size_t capacity;
    size_t length;

public:
    // normal interface methods
};

关键点在于有两个不同的内存块:一个用于
字符串
对象本身,包含上面显示的成员,另一个用于字符串的内容。当您放置
new
时,只有字符串对象被放置到提供的内存中,而不是存储字符串内容的
缓冲区的内存中。这是由
字符串根据需要自动单独分配的。

这就是我所缺少的。非常感谢。吹毛求疵:我看了一些标准库实现,它们都是用
char*end\ux
而不是
length()
,这意味着(i=s.begin();i!=s.end();++i)
的典型迭代ala
将有一个非常便宜的
end()
,但是
size()
将需要一个指针减法。这里没有什么大问题,也没有什么特别相关的,但我想在你的脑海中记住……@TonyD VS8和G++4.3.4使用容量和长度字段,而不是
结束
字段。在任何情况下,这个答案都不是关于如何有效实现
std::string
,而是一个便于理解的教学示例。当
string(“hiiii…”)
运行时,它可能会执行
新字符[]
,以获得额外的内存来存储文本,如果抛出,那么重要的是
p
不是
delete
d(这将是未定义的行为),而是
buf
delete[]
ed(否则会出现内存泄漏)。因此,即使不是“容易发生异常”,所有异常都是容易出错的。