Я играю с некоторыми базовыми элементами 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. Почему нет ошибок? Разве я не прошел границу выделенного пространства?
В случае, если код в порядке... Почему пример в ссылке? В другом (более вероятном) случае... Каковы риски?
Благодарю!
Вы не получаете никаких ошибок, потому что C и C++ не выполняют проверку границ. Вы переписали разделы памяти, которые вы не использовали, но вам повезло, и это было неважно. Сравните это с тем, чтобы положить гвоздь в стену, где вы знаете там шпильки. Если вы пропустили шпильки, большую часть времени вы просто кладете дыру в штукатурку, но это опасно продолжать делать это, потому что в конце концов вы нажмете один из живых проводов.
Вы прошли через границу выделенной памяти.
Однако printf не беспокоит, какой размер объявленной памяти. Все, что он заботится, это начнется с самого начала и продолжится, пока не найдет 0.
Случай, который вы создали, является неопределенным поведением. Могут быть некоторые другие данные сразу после выделенной области (возможно, другая переменная), и в этом случае она будет повреждена. Если следующая часть - нераспределенная память, вы можете выйти без видимой проблемы. И если память сразу после вашей выделенной памяти принадлежит другому процессу, вы увидите хороший и аккуратный дефект сегментации. Последствия могут быть еще хуже, поэтому лучше не пытаться этого нигде.
в комментариях в 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 байта, ваша программа запускается без ошибок. Это одна из возможностей правильно выполнить вашу программу.