Этот код, кажется, добавляет символы вне выделенного диапазона

0

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

Дело в том, что после просмотра примера в www.cplusplus.com/reference/cstdlib/malloc/ я нашел себя с этим кодом:

#include <stdio.h>

int main (void) {
  char *str;
  str = (char*) malloc(2);
  str[0] ='8';
  str[1] ='8';
  str[2] ='6';
  str[3] ='\0';
  printf ("%s\n",str);
}

И компиляция с:

gcc -O0 -pedantic -Wall test2.cpp

(версия gcc 4.7.2)

У меня нет ошибок и выход 886. Почему у меня нет ошибок? Разве я не прошел границу выделенного пространства?

У меня не было ошибок, и я получил результат 886. Почему нет ошибок? Разве я не прошел границу выделенного пространства?

В случае, если код в порядке... Почему пример в ссылке? В другом (более вероятном) случае... Каковы риски?

Благодарю!

  • 0
    Любой приличный инструмент статического анализа (например, cppcheck) должен сказать вам (я думаю, что даже Eclipse CDT C ++ SA анализатор делает).
  • 0
    Благодарю. Это очень далеко от C ++? Каковы основные отличия? Как новичок может отличить одно от другого? (С Fortran мне потребовалось несколько лет, чтобы узнать, какой синтаксис исходит от каждой версии)
Показать ещё 1 комментарий
Теги:
string
malloc

3 ответа

5
Лучший ответ

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

3

Вы прошли через границу выделенной памяти.

Однако printf не беспокоит, какой размер объявленной памяти. Все, что он заботится, это начнется с самого начала и продолжится, пока не найдет 0.

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

  • 0
    Большое спасибо! очень быстрые ответы! Отличный форум, отличные пользователи.
1

в комментариях в malloc.c glibc можно найти следующее:

Минимальные накладные расходы на каждый выделенный блок: 4 или 8 байтов. Каждый malloced chunk имеет скрытое слово для определения размера и статуса служебных данных.

Минимальный выделенный размер: 4 байта ptrs: 16 байт (включая 4 служебных) 8-байтных ptrs: 24/32 байта (в том числе 4/8 служебных)

Когда кусок освобождается, 12 (для 4 байт ptrs) или 20 (для 8 байт
ptrs, но 4 байта) или 24 (для 8/8) необходимы дополнительные байты; 4 (8) для конечного поля размера и 8 (16) байтов для указателей свободных списков. Таким образом, минимальный выделяемый размер составляет 16/24/32 байта.

Поскольку минимальный размер будет 16/24/32, так как он превышает 3 байта, ваша программа запускается без ошибок. Это одна из возможностей правильно выполнить вашу программу.

  • 1
    Это одна (!) Из всех возможных реализаций - malloc для встроенной системы с крошечной памятью может выделять именно запрошенную память (не более того)
  • 0
    @ DieterLücking да, это одна из возможных реализаций, я думаю, он сталкивался с такой реализацией malloc.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню