Динамическая строка без realloc [duplicate]

Замечания:

  • Это не сработает, если class A имеет объект class B в качестве члена или наоборот.
  • Переслать декларацию - это путь.
  • Применяется порядок декларирования (именно поэтому вы выходите из определений). Если оба класса называют функции другого, вы должны перенести определения.

Читайте FAQ:

5
задан singingsingh 14 September 2012 в 07:17
поделиться

4 ответа

Я предполагаю, что вы приходите с Java или Java-подобного языка, где, когда вы выходите из границы массива, вы получаете исключение «index index out of bounds».

Ну, C ожидает от вас большего; он экономит пространство, которое вы просите, но он не проверяет, выходите ли вы за пределы этого накопленного пространства. Как только вы это сделаете, как указано выше, у программы есть такое ужасное неопределенное поведение.

И помните о будущем, если у вас есть ошибка в вашей программе, и вы не можете ее найти, и когда вы перейдите код / ​​отлаживайте его, все кажется ОК, есть хороший шанс, что вы «вне пределов» и доступ к нераспределенному месту.

3
ответ дан RastaJedi 24 August 2018 в 05:59
поделиться

Потому что неопределенное поведение == все может случиться. Вам не повезло, что это не сбой, такое поведение может потенциально скрывать ошибки.

Что касается a, определяющего дважды - это ошибка в компиляторе.

9
ответ дан Luchian Grigore 24 August 2018 в 05:59
поделиться

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

0
ответ дан mark 24 August 2018 в 05:59
поделиться

Объявление двух переменных, называемых a, безусловно, является ошибкой; если ваш компилятор соглашается с этим, тогда он сломан. Я предполагаю, что вы имеете в виду, что вы по-прежнему не получаете ошибку, если вы замените одно объявление другим.

Доступ к массиву не проверен диапазоном. Во время компиляции размер массива часто неизвестен, и язык не требует проверки даже тогда, когда он есть. Во время выполнения проверка снизит производительность, что противоречит философии C ++, которая не платит за то, что вам не нужно. Таким образом, доступ за пределами массива дает неопределенное поведение, и программист должен убедиться, что этого не происходит.

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

Если вы хотите быть безопасным, вы можете использовать std::vector и получать доступ только к его элементам, используя функцию at(). Это проверит индекс и выдаст исключение, если оно выходит за пределы допустимого диапазона. Он также будет управлять распределением памяти для вас, исправляя утечку памяти в вашем примере.

8
ответ дан Mike Seymour 24 August 2018 в 05:59
поделиться
Другие вопросы по тегам:

Похожие вопросы: