分配后未更新C ++字符串大小

时间:2016-02-11 07:47:06

标签: c++ arrays string char

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。为什么会这样?

5 个答案:

答案 0 :(得分:10)

operator[]不会调整字符串的大小。而你对索引5,6和7的调用超出了范围和未定义的行为。使用resize将字符串设置为特定大小,或push_backoperator+=添加字符。

另请注意,您无需手动将std::string置零。该课程将自行处理。虽然如果你真的想要它们,你可以在那里嵌入零,并且它们将被视为字符串长度的一部分。

答案 1 :(得分:6)

10根本不会增长字符串,只是告诉容器reserve enough memory至少s2[5]个字符。它没有用任何东西填充预留的空间。

因此,当您对其进行索引10时,您基本上在“已使用”字符串的边界(即其大小)之外进行索引,这是未定义的行为。

要调整大小,您可以使用s2.resize(10);。这将适当地分配和填充字符串,其大小为operator+=。要同时分配和插入字符,您还可以使用push_back()s2[7] = '\0';

旁注:不需要stringc_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]