Я полагаю, что это было бы злоупотреблением. http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.10 состояния "Элемент FIELDSET позволяет авторам группироваться тематически связанный средства управления и маркировки".
Это неопределенное поведение (скорее всего, приведет к повреждению кучи или немедленному сбою программы), и вам никогда не следует этого делать. Освободите память только с примитивом, соответствующим тому, который использовался для выделения этой памяти.
Нарушение этого правила может привести к правильному функционированию по совпадению, но программа может выйти из строя после того, как что-либо изменится - компилятор, среда выполнения, настройки компилятора. Никогда не следует полагаться на такое правильное функционирование и ожидать этого.
delete []
использует служебные данные компилятора для определения количества элементов. Обычно при вызове new []
выделяется больший блок, номер сохраняется в начале, а вызывающему абоненту дается адрес после сохраненного номера. В любом случае delete []
полагается на блок, выделяемый new []
, больше ничего. Если вы соедините что-либо, кроме new []
с delete []
или наоборот, вы столкнетесь с неопределенным поведением.
Прочтите FAQ: 16.3 Могу ли я выделить указатели free () с помощью new? Могу ли я удалить указатели, выделенные с помощью malloc ()?
Имеет ли значение в приведенном выше случае, поскольку все элементы s размещены непрерывно, и невозможно удалить только часть массива?
Да, это так.
Как может delete [] определить количество Объектов помимо первого, разве это не означает, что он должен знать размер выделенной области памяти?
Компилятор должен знать. См. FAQ 16.11
Поскольку компилятор хранит эту информацию.
Я имею в виду, что компилятору требуются разные delete
s для генерации соответствующего бухгалтерского кода. Надеюсь, теперь это ясно.
Да, это опасно!
Не делайте этого!
Это приведет к сбоям программы или еще хуже!
Для объектов, выделенных с помощью new
] вы ДОЛЖНЫ использовать delete
;
Для объектов, выделенных с помощью new []
, вы ДОЛЖНЫ использовать delete []
;
Для объектов, выделенных с помощью malloc ()
или calloc ()
, вы ДОЛЖНЫ использовать free ()
;
Имейте в виду, что во всех этих случаях нельзя повторно удалить / освободить уже удаленный / освобожденный указатель. free
также НЕ может вызываться с нулевым значением. вызов delete / delete []
с NULL является допустимым.
Да, существует реальная практическая опасность. Не говоря уже о деталях реализации, помните, что функции operator new / operator delete
и operator new [] / operator delete []
могут быть заменены полностью независимо. По этой причине разумно думать о new / delete
, new [] / delete []
, malloc / free
и т. Д. Как о разных, полностью независимых методы распределения памяти, не имеющие абсолютно ничего общего.
Удаляет ли освобождение элементов после первого в массиве?
Нет. delete освободит только первый элемент, независимо от того, какой компилятор вы это делаете. В некоторых случаях это может сработать, но это случайно.
Имеет ли это значение в приведенном выше случае, поскольку все элементы s распределены непрерывно, и не должно быть возможности удалить только часть массива?
Зависит от того, как память позиционируется как свободная. Опять же, зависит от реализации.
Для более сложных типов удалит ли вызов деструктора объектов за пределами первого?
Нет. Попробуйте следующее:
#include <cstdio>
class DelTest {
static int next;
int i;
public:
DelTest() : i(next++) { printf("Allocated %d\n", i); }
~DelTest(){ printf("Deleted %d\n", i); }
};
int DelTest::next = 0;
int main(){
DelTest *p = new DelTest[5];
delete p;
return 0;
}
Как удалить [] определить количество Объекты за пределами первого, не это означает, что он должен знать размер выделенная область памяти?
Да, размер где-то хранится. Где он хранится, зависит от реализации. Например, распределитель может сохранить размер в заголовке, предшествующем выделенному адресу.
Что, если бы область памяти была выделены с некоторым выступом для причины производительности? Например один можно предположить, что не все распределители обеспечит детализацию однобайтный. Тогда любой конкретный выделение может превышать требуемое размер каждого элемента в целом элемент или более.
Именно по этой причине возвращаемый адрес выравнивается по границам слова. "Свес" можно увидеть с помощью оператора sizeof, и он также применяется к объектам в стеке.
Для примитивных типов, таких как char, int, есть ли разница между ...?
Да. malloc и new могут использовать отдельные блоки памяти. Даже если бы это было не так, лучше не предполагать, что они одинаковы.
Рэймонд Чен (разработчик Microsoft) опубликовал подробную статью, посвященную масштабированию и векторному удалению, а также рассказал о различиях. См:
http://blogs.msdn.com/oldnewthing/archive/2004/02/03/66660.aspx
Это неопределенное поведение. Отсюда ответ: да, опасность может быть. И невозможно точно предсказать, что вызовет проблемы. Даже если это сработает один раз, будет ли работать снова? Это зависит от типа? Количество элементов?
Для примитивных типов, таких как char, int, есть ли разница между:
Я бы сказал, вы получите неопределенное поведение. Так что на стабильное поведение рассчитывать не стоит. Вы всегда должны использовать пары new / delete, new [] / delete [] и malloc / free.
Хотя может показаться логичным, что вы можете смешивать new [] и free или delete вместо delete [], это делается при условии, что компилятор упрощенным, т.е. он всегда будет использовать malloc () для реализации выделения памяти для new [].
Проблема в том, что если ваш компилятор имеет достаточно умный оптимизатор, он может увидеть, что нет соответствующего "delete []" в новый [] для созданного вами объекта. Следовательно, можно предположить, что он может получить память для него из любого места, включая стек, чтобы сэкономить затраты на вызов реального malloc () для new [].
На шаге 1 читаем следующее: what-is-the-разница-между-new-delete-and-malloc-free
Вы смотрите только на то, что видите на стороне разработчика.
What you are not considering is how the std lib does memory management.
The first difference is that new and malloc allocate memroy from two different areas in memory (New from FreeStore and malloc from Heap (Don't focus on the names they are both basically heaps, those are just there official names from the standard)). If you allocate from one and de-allocate to the other you will messs up the data structures used to manage the memory (there is no gurantee they will use the same structure for memory management).
When you allocate a block like this:
int* x= new int; // 0x32
Memory May look like this: It probably wont since I made this up without thinking that hard.
Memory Value Comment
0x08 0x40 // Chunk Size
0x16 0x10000008 // Free list for Chunk size 40
0x24 0x08 // Block Size
0x32 ?? // Address returned by New.
0x40 0x08 // Pointer back to head block.
0x48 0x0x32 // Link to next item in a chain of somthing.
The point is that there is a lot more information in the allocated block than just the int you allocated to handle memory management.
The standard does not specify how this is done becuase (in C/C++ style) they did not want to inpinge on the compiler/library manufacturers ability to implement the most effecient memory management method for there architecture.
Taking this into account you want the manufacturer the ability to distinguish array allocation/deallocation from normal allocation/deallocation so that it is possable to make it as effecient as possable for both types independantly. As a result you can not mix and match as internally they may use different data structures.
If you actually analyse the memory allocation differences between C and C++ applications you find that they are very different. And thus it is not unresonable to use completely different techniques of memory management to optimise for the application type. This is another reason to prefer new over malloc() in C++ as it will probably be more effecient (The more important reason though will always be to reducing complexity (IMO)).