Есть еще вариант когда почта предварительно должна быть одобрена. Там назначается пользователь на группу ящиков и все их письма идут через этого пользователя. Возможно это не в стандарт, а энтерпрайз версии
@brutal_lobster 5. чтобы изменить объект и пересчитать длину и площадь =) я думаю что там стоит проверку добавить. А возможность изменить координаты, это по сути движение объекта, т.е. если мы имеем два таких объекта, то можно посчитать пересекаются они или нет (к примеру).
@brutal_lobster благодарю за развернутый ответ. 1.2. учту, тесты всегда так писал, новичку проще, но видимо привыкать не стоит... 4. 5. ок. 6. торопился =) нужно было math.h подключать и там можно было взять пи, но наизусть не знаю.
Понял. У меня была мысль что malloc записывает куда-то адрес начала и длину блока, но все-равно было любопытно сработает ли очистка блока, даже если ткнули в его середину. Спасибо
В варианте один - выводит мусор, в варианте два падает. Код выполняется не одновременно, т.е. это разные программы.
Вот, в первом варианте если я вывожу указатель и значения - падения нет
А во втором - падает даже если я просто указатель вывожу.
И правда срезало... Суть
std::cout << data << std::endl; // ошибка
std::cout << start << std::ednl; // ошибка
Почему если мы очищаем data и он находится в середине то получаем ошибку, ведь UB там в обоих вариантах? Или это уже специфика malloc?
Здесь не совсем предел массива был, а чтение и попытка модификации памяти за областью массива, в другой ветке комментариев мне доступно объяснили что не так.
Материал может и правда был неудачно выбран, но отвергая - предлагайте.
@VoidEx , еще вопрос возник. Про умные указатели почитал, в целом к ним нужно стремиться, шикарно закрывают эти косяки.
Вот глядите,
void * data = malloc(buffer*sizeof(int));
void * start = data;
/*манипуляции с значениями по адресу, data в середине буфера или на последнем элементе*/
А представьте что материал книг дается сложно, а общение, к примеру с @VoidEx , дало куда больше. В книге не задашь вопрос и если вылезла ошибка, то приходится вот так лезть в инет и получать комменты вида: "Может стоит почитать книги...". Кстати, Вы не предложили ни одной (хотя бы с фразой - в это шикарно описано, учился сам и все понял).
До кучи, большинство примеров из книг уже содержат работу с указателями, но она всегда рассматривается позднее, в итоге не имея преподавателя/научрука можно огрести не хилую кашицу, упорядочить которую очень не просто.
Я считал что раз передается указатель, то free очищая память должна его сослать в nullptr (мне казалось такое поведение логичным, чтобы программа не сбоила дальше).
Получается что после такой чистки имеет смысл принудительно присваивать указателям nullptr, чтобы в дальнейшем избегать проблем. Правильно?
Т.е. пользовались мы указателем, затем блок памяти почистили, следом ему присвоили nullptr и дальше можем спать спокойно.
Да, проверил экспериментально, все получилось. При этом я передал во free указатель на начало блока (т.е. start), а дальше просто прошелся указателем data по предыдущим значениям, но почему при этом start не стал равен nullptr?
free только пометил блок как чистый и заполнил его мусором, но указатели все еще рабочие, это нормально?
А "delete p; - UB", потому что мы удалили саму ссылку, но не объект или вообще на совести компилятора, тут как раз вроде проще. Это же будет утечка памяти, правильно?
Но я верно написал что по окончании работы скорее всего data будет ссылаться на end, поэтому чистить блок нужно через free(start); ? Ведь это и есть начало блока. Хорошо, а разметку блока можно как-то посмотреть или это просто на программисте лежит? Блок разметили, начало и размер храним. Тогда как free знает сколько нужно очистить. Вот я занял блок 1024 байта, как free знает что нужно очистить именно их или получается чистится только первый элемент и нужно вызывать free в цикле для всех разыменовывая указатель?
Например:
void *data = nullptr;
void *end = nullptr;
data = malloc(sizeof(int)*20);
if (data == nullptr)
{ return 0;}
void *start = (int *)data;
end = ((int *)data + 20);
for (int i = 0; i <= 19; i++)
{
*(int *)data = i;
data = (int *)data + 1;
}
data = (int *)start;
while (data != end)
{
std::cout << *(int *)data << std::endl;
data = (int *)data + 1;
}
free(start); // т.к. если вызову free(data); то огребу ошибку, т.к. этот блок не мой. Но при этом data != nullptr, а вот start как раз очистился, только теперь вопрос в том очистился ли весь блок в 80 байт или только первые четыре байта.