неожиданная успешная копия на основе strlen - PullRequest
1 голос
/ 02 декабря 2011

Я проверял свои навыки с помощью указателей и буфера в C ++.Я попробовал код ниже, и все работает отлично.Без утечек, без сбоев, ничего.

Если честно, я этого не ожидал.

Когда я звоню char* buf2 = new char[strlen(buf)], я не ожидал, что srlen(buf) вернет правильный размер.Я всегда думал, что для работы strlen нужна завершенная строка NULL.Здесь дело не в этом, так почему работает этот код?

        int main(){
             const char* mystr = "mineminemine";
             char* buf = new char[strlen(mystr)];
             memcpy(buf, mystr, strlen(mystr));

             char* buf2 = new char[strlen(buf)];
             memcpy(buf2, buf, strlen(buf));

             delete[] buf2;
             delete[] buf;
        }

Ответы [ 2 ]

6 голосов
/ 02 декабря 2011

Это называется неопределенным поведением - программа работает, но вы не можете на это полагаться.

Когда выделяется память, где-то появляется пустой символ, который находится достаточно близко к началу буфера и программы.технически может получить доступ ко всей памяти между этим нулевым символом и началом буфера, чтобы вы не наблюдали сбой.

Вы не можете полагаться на такое поведение.Не пишите такой код, всегда выделяйте достаточно места для хранения завершающего нулевого символа.

0 голосов
/ 02 декабря 2011

Рассмотрим другой способ сделать то же самое:

 int main(){
          std::string mystr = "mineminemine";
          std::string mystr2 = mystr;
 }

Внутренне у вас есть буфер с добавленным нулевым завершающим символом.Когда вы копируете стандартную строку, вам не нужно беспокоиться о том, чтобы отслеживать начало и конец буфера.

Теперь, учитывая время жизни строк, эти две переменные объявляются в стеке и уничтожаются при основномвыходит за рамки (например, терминация).Если вам нужны строки для совместного использования между объектами, и вы не обязательно знаете, когда они будут уничтожены, я рекомендую рассмотреть возможность использования общих указателей boost.

...