c ++ Почему выделяется память при передаче строкового литерала в функцию? - PullRequest
4 голосов
/ 30 мая 2011

У меня есть его код:

int setAttrib(const string& name, int components){    
    // here I don't even touch 'name'
    if(components == 2) return 3;
    else return 1;
}

И я вызываю функцию следующим образом:

setAttrib("position", 3);

Я профилирую память с помощью профилировщика xcode и в вызове функции std ::Строка делает распределение.
Почему это?

РЕДАКТИРОВАТЬ:

Каков наилучший способ избежать этого распределения?так как я вызываю эту функцию много , и примерно через 10 секунд я выделяю около 10 МБ в этой строке.

Спасибо.

Ответы [ 3 ]

13 голосов
/ 30 мая 2011

Вы запрашиваете const string&, но передаете const char*.Таким образом, компилятору необходимо создать временный объект правильного типа.

Тот факт, что "position" - это не std::string, а char const*, является скорее исторической случайностью (унаследованной от C, когдане был string классом в C ++), чем дизайнерское решение, но, тем не менее, имейте в виду.

6 голосов
/ 30 мая 2011

Поскольку std::string обычно выделяет кучу памяти для хранения строки.В этом случае std::string неявно создается из строкового литерала (который сам по себе находится в статическом хранилище).Некоторые реализации строк используют небольшой буфер для обслуживания небольших строк, но здесь это не так, и в любом случае зависит от реализации.

Неважно, что name не используется - в основном, setAttrib("position", 3) является сокращением для setAttrib(std::string("position"), 3);, поэтому, когда элемент управления вводит setAttrib, память уже выделена (конечно, в вашем изолированном примере кода компилятор мог бы встроить getAttrib и затем отброситьПостроение строк вообще, но это оптимизация компилятора, а не языковая функция).

Обратите внимание, что временные объекты, созданные во время вызова функции, автоматически уничтожаются при возврате функции, поэтому утечка памяти отсутствует.

5 голосов
/ 30 мая 2011

Чтобы вызвать функцию, компилятору необходимо построить все параметры , const string& name включены, единственный способ сделать это в вашем случае (вместо этого вы передаете строковый литерал ) должен создать временную std::string, и это требует выделения кучи памяти в большинстве реализаций. Не имеет значения, используете ли вы значение внутри функции или нет.

...