int main(int argc, char const *argv[])
{
const char *s1 = "hello";
string s2;
s2 = s1;
s2.reserve(10);
s2[5] = '.';
s2[6] = 'o';
s2[7] = '\0';
cout << "[" << s1 << "] [" << s2 << "]" << endl;
return 0;
}
上述代码无法正确打印s2
。而不是hello.o
它始终打印hello
。似乎s2
的大小始终在第一次分配后保持为5。为什么会这样?
答案 0 :(得分:10)
operator[]
不会调整字符串的大小。而你对索引5,6和7的调用超出了范围和未定义的行为。使用resize
将字符串设置为特定大小,或push_back
或operator+=
添加字符。
另请注意,您无需手动将std::string
置零。该课程将自行处理。虽然如果你真的想要它们,你可以在那里嵌入零,并且它们将被视为字符串长度的一部分。
答案 1 :(得分:6)
10
根本不会增长字符串,只是告诉容器reserve enough memory至少s2[5]
个字符。它没有用任何东西填充预留的空间。
因此,当您对其进行索引10
时,您基本上在“已使用”字符串的边界(即其大小)之外进行索引,这是未定义的行为。
要调整大小,您可以使用s2.resize(10);
。这将适当地分配和填充字符串,其大小为operator+=
。要同时分配和插入字符,您还可以使用push_back()
或s2[7] = '\0';
。
旁注:不需要string
。 c_str()
类在内部管理static SecondViewController *sharedVCInstance = nil;
+ (SecondViewController *)sharedInstance
{
static dispatch_once_t onceToken = 0;
dispatch_once (&onceToken, ^{
if(sharedVCInstance == nil)
sharedVCInstance = [[SecondViewController alloc] init];
});
return sharedVCInstance;
}
等方法所需的任何NUL终结。您不需要自己添加NUL。
答案 2 :(得分:4)
您应该使用s2.resize()
代替s2.reserve()
。
答案 3 :(得分:2)
std::string::reserve
仅分配内存,但不调整字符串大小。在您的示例中:
s2 = s1; // Resize string to 6 characters
s2.reserve(10); // Allocate another 4 char, but not resize
s2[5] = '.'; // Write '.' to some memory, but the string is still not resized.
简单的解决方法是使用std::string::resize
代替reserve
。
答案 4 :(得分:0)
简答:使用resize(10)而不是reserve(10)
答案很长: 在std :: string的实现中,有两个变量大小和容量。 容量是您为字符串分配的内存量。 大小是字符串中允许的有效元素数(在您的情况下为char)。 请注意,容量始终小于或等于大小。 当你调用reserve()时,你正在改变容量。 当您的呼叫调整大小()时,您可能不仅要更改大小,而且如果大小&gt;您还将更改容量。容量,然后适用该公式:
if (size > capacity){
capacity = max(size, capacity*2); //Why multiply capacity by 2 here? This is to achieve amortized O(1) while resizing
}
以下是OP想要的代码示例以及更多用于更好地解释大小和容量的代码
#include <iostream>
#include <string.h>
using namespace std;
int main(int argc, char const *argv[])
{ const char *s1 = "hello";
string s2;
s2 = s1;
cout << "length of s2 before reserve: " << s2.length() << endl;
cout << "capacity of s2 before reserve: " << s2.capacity() << endl;
s2.reserve(10);
cout << "length of s2 after reserve: " << s2.length() << endl; //see how length of s2 didn't change?
cout << "capacity of s2 after reserve: " << s2.capacity() << endl;
s2.resize(8); //resize(10) works too, but it seems like OP you only need enough size for 8 elements
cout << "length of s2 after resize: " << s2.length() << endl; //size changed
cout << "capacity of s2 after resize: " << s2.capacity() << endl; //capacity didn't change because size <= capacity
s2[5] = '.';
s2[6] = 'o';
s2[7] = '\0';
cout << "[" << s1 << "] [" << s2 << "]" << endl;
// You're done
// The code below is for showing you how size and capacity works.
s2.append("hii"); // calls s2.resize(11), s[8] = 'h', s[9] = 'i', s[10] = 'i', size = 8 + 3 = 11
cout << "length of s2 after appending: " << s2.length() << endl; // size = 11
cout << "capacity of s2 after appending: " << s2.capacity() << endl; //since size > capacity, but <= 2*capacity, capacity = 2*capacity
cout << "After appending: [" << s1 << "] [" << s2 << "]" << endl;
return 0;
结果:
length of s2 before reserve: 5
capacity of s2 before reserve: 5
length of s2 after reserve: 5
capacity of s2 after reserve: 10
length of s2 after resize: 8
capacity of s2 after resize: 10
[hello] [hello.o]
length of s2 after appending: 11
capacity of s2 after appending: 20
After appending: [hello] [hello.ohii]