одиночная строка в стиле c, полная мусора - PullRequest
2 голосов
/ 04 июня 2011

Жаль, что я не могу понять такую ​​основную вещь в c ++, но строки в стиле c работают так, как я и не ожидал. Например, я создаю это так: char* cstr = new char[1];

Инициализируется: Íýýýýý «« «« «« «« ». Как обычно, я могу установить только первый символ, потому что другие на самом деле не существуют (или я думал, что они не существуют). При работе со строками в стиле c все это барахло попадает и все отлично работает.

Теперь я смешал std :: string с этими c-stlye, и я получил беспорядок. С этим кодом:

std::string str = "aaa";</p> <p>str += cstr;

В итоге я получаю: aaaÍýýýýý «« «« «« «« », но теперь эти символы фактически существуют, так как string.size () возвращает длину, включая этот мусор.

Я не могу найти, почему это происходит, но это должно быть связано с созданием строки, потому что что-то вроде char * cstr = "aaa" приводит к aaa без какого-либо дополнительного мусора, но попытка изменить инициализированную строку таким образом приводит к нарушение доступа к памяти. Может ли кто-нибудь объяснить мне это поведение, пожалуйста? Спасибо!

PS: Не удалось загрузить мой JavaScript, поэтому, если кто-то сможет правильно отформатировать этот пост, я буду рад!

Ответ: О, боже! Как я мог забыть об этом ... спасибо всем за, ну, немедленный ответ. Лучший из них был от Minitech, поэтому я отмечу это как ответ, как только загрузится мой java-скрипт: /

Ответы [ 5 ]

6 голосов
/ 04 июня 2011

Все строки в стиле C заканчиваются нулем. Итак, строка, инициализированная с помощью new char[1], оставляет место для символов. Вы не можете установить для первого символа ничего, кроме \0, в противном случае обычные строковые операции будут продолжать считываться в память, пока не найдут ноль. Поэтому используйте new char[2] вместо.

5 голосов
/ 04 июня 2011

При работе со строками в стиле C вам необходимо иметь нулевой терминатор:

char* cstr = new char[2];
cstr[0] = 'X';
cstr[1] = '\0';

Сказав все это, действительно плохой код, чтобы сделать вышеописанное.Просто используйте std::string, если у вас нет очень веских причин.Он заботится о распределении и освобождении памяти для вас.

2 голосов
/ 04 июня 2011

Для строк в стиле C требуется терминатор NUL ('\0'); они не имеют длины, связанной с ними, как строки C ++. Таким образом, ваша односимвольная строка должна быть new char[2]; он не будет инициализирован; и вам нужно убедиться, что он завершен с \0.

1 голос
/ 04 июня 2011

Строки c-стиля разделены NULL.Таким образом, чтобы игнорировать любой мусор в памяти, вам нужно поместить NULL-байт ('\0') в тело строки.В противном случае функция системной библиотеки будет проверять все байты, начиная с начала строки, до тех пор, пока они не встретят в памяти байт NULL (который будет в некоторой случайной позиции).

Это также означает, что иметь строку в стиле cодин символ, который вам действительно нужно выделить 2 байта: один для значащего символа и второй для '\0'.

1 голос
/ 04 июня 2011

Когда вы используете new char[1], вы запрашиваете пространство для массива символов.Нет запроса на инициализацию указанных символов.Таким образом, «мусор», который вы видите, является неинициализированной памятью.Перед обработкой массива как строки в стиле C, вы должны сделать следующее:

cstr[0] = '\0';
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...