2017-02-16 11 views
1

В следующем коде:Почему оператор Dimof на std :: string дает неожиданный результат?

#include <iostream> 
#include <string> 
using namespace std; 

int main() { 
    char buff[100]; 
    _snprintf(buff, sizeof(buff), "%s %d", "Name",2); //snprintf incase of ideone 
    string buffAsStdStr = buff; 
    cout<<buffAsStdStr<<endl; 
    cout<<"len: "<<buffAsStdStr.length()<<endl; 
    cout<<sizeof(buffAsStdStr)<<endl; 

    return 0; 
} 

Длина строки в buffAsStdStr составляет 6, но значение по SizeOf шоу 28, когда я бегу в Visual Studio 2012 и 32 в ideone. Ожидаемый размер 7, включая конечный символ NULL.

В чем причина этого неожиданного результата оператора sizeof? Почему результат меняется в визуальной студии и идеоне?

+5

Причина в том, что ваши ожидания были неправильными :) – StoryTeller

+0

Вопрос имеет смысл, особенно для тех, кто начинает изучать C++. –

+2

@ Mr.C64 да Я новичок. Теперь понятно и кристально понятно. Всем спасибо! –

ответ

7

sizeof из std::string экземпляра просто возвращает размер в байтах «внутреннего представления» в std::string, т.е. вы можете думать о нем, как сумма sizeof с членов данных, каждый из std::string «s (там может также включается дополнение).

Например, в 32-битных отладочных сборках с VS2015, sizeof(std::string) возвращает 28; в 64-битных отладочных сборках я получаю 40; в 32-разрядные версии релиза я получаю 24, и в 64-битной версии релиза 32.

Это потому, что представление внутренний из std::stringизменения с различными вариантами сборки: например, отладочные сборки обычно содержат дополнительную механику, помогающую выявлять ошибки, которые увеличивают размер представления; Более того, в 64-битные сборки указатели крупнее, так что снова в размер увеличивается по отношению к 32-битные сборки и т.д.

Таким образом, число, которое вы получаете от sizeof вызывается на std::string, например, в общем разные из числа char s, которые создают текст строки. Чтобы получить этот номер, вы должны позвонить std::string::size or std::string::length.

+0

Интересно. В Visual Studio буфер с малой строкой составляет 16 байт. Я немного удивлен, что они не сделали это 20 в 32-битной сборке, поэтому размер был кратным 8. Возможно, им больше не нужны 32-битные сборки. –

+0

@MartinBonner: В VS2015 'sizeof (std :: string)' is ** 24 ** (3x8) в 32-битных сборках _release_ :) –

3

Вы должны использовать std::string::size, or std::string::length.

sizeof возвращает размер объекта, это не количество символов.

+0

std :: string :: size и std :: string :: length оба возвращаются одинаково. Как 6. –

+0

Да. Он не учитывает нулевой ограничитель. – ForEveR

+0

@ShameelMohamed Ты не понимаешь, правда? –

3

Причина в том, что sizeof(buffAsStdStr) - это не длина строки, а размер экземпляра std::string, и каждый экземпляр заданного типа имеет тот же размер.

Результат sizeof определяется во время компиляции, и если у вас есть объект o типа T, sizeof(o) и sizeof(T) эквивалентны.

Кроме того, std::string не требуется для хранения конечного нулевого символа и может содержать «не заканчивающиеся» нулевые символы.