Есть ли опасность в вызове свободного (), или удалите вместо, удаляют []? [дубликат]

Я полагаю, что это было бы злоупотреблением. http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.10 состояния "Элемент FIELDSET позволяет авторам группироваться тематически связанный средства управления и маркировки".

6
задан Community 23 May 2017 в 12:00
поделиться

10 ответов

Это неопределенное поведение (скорее всего, приведет к повреждению кучи или немедленному сбою программы), и вам никогда не следует этого делать. Освободите память только с примитивом, соответствующим тому, который использовался для выделения этой памяти.

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

delete [] использует служебные данные компилятора для определения количества элементов. Обычно при вызове new [] выделяется больший блок, номер сохраняется в начале, а вызывающему абоненту дается адрес после сохраненного номера. В любом случае delete [] полагается на блок, выделяемый new [] , больше ничего. Если вы соедините что-либо, кроме new [] с delete [] или наоборот, вы столкнетесь с неопределенным поведением.

15
ответ дан 8 December 2019 в 02:24
поделиться

Прочтите FAQ: 16.3 Могу ли я выделить указатели free () с помощью new? Могу ли я удалить указатели, выделенные с помощью malloc ()?

Имеет ли значение в приведенном выше случае, поскольку все элементы s размещены непрерывно, и невозможно удалить только часть массива?

Да, это так.

Как может delete [] определить количество Объектов помимо первого, разве это не означает, что он должен знать размер выделенной области памяти?

Компилятор должен знать. См. FAQ 16.11

Поскольку компилятор хранит эту информацию.

Я имею в виду, что компилятору требуются разные delete s для генерации соответствующего бухгалтерского кода. Надеюсь, теперь это ясно.

10
ответ дан 8 December 2019 в 02:24
поделиться

Да, это опасно!

Не делайте этого!

Это приведет к сбоям программы или еще хуже!

Для объектов, выделенных с помощью new ] вы ДОЛЖНЫ использовать delete ;

Для объектов, выделенных с помощью new [] , вы ДОЛЖНЫ использовать delete [] ;

Для объектов, выделенных с помощью malloc () или calloc () , вы ДОЛЖНЫ использовать free () ;

Имейте в виду, что во всех этих случаях нельзя повторно удалить / освободить уже удаленный / освобожденный указатель. free также НЕ может вызываться с нулевым значением. вызов delete / delete [] с NULL является допустимым.

4
ответ дан 8 December 2019 в 02:24
поделиться

Да, существует реальная практическая опасность. Не говоря уже о деталях реализации, помните, что функции operator new / operator delete и operator new [] / operator delete [] могут быть заменены полностью независимо. По этой причине разумно думать о new / delete , new [] / delete [] , malloc / free и т. Д. Как о разных, полностью независимых методы распределения памяти, не имеющие абсолютно ничего общего.

3
ответ дан 8 December 2019 в 02:24
поделиться

Удаляет ли освобождение элементов после первого в массиве?

Нет. 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 могут использовать отдельные блоки памяти. Даже если бы это было не так, лучше не предполагать, что они одинаковы.

2
ответ дан 8 December 2019 в 02:24
поделиться

Рэймонд Чен (разработчик Microsoft) опубликовал подробную статью, посвященную масштабированию и векторному удалению, а также рассказал о различиях. См:

http://blogs.msdn.com/oldnewthing/archive/2004/02/03/66660.aspx

2
ответ дан 8 December 2019 в 02:24
поделиться

Это неопределенное поведение. Отсюда ответ: да, опасность может быть. И невозможно точно предсказать, что вызовет проблемы. Даже если это сработает один раз, будет ли работать снова? Это зависит от типа? Количество элементов?

1
ответ дан 8 December 2019 в 02:24
поделиться

Для примитивных типов, таких как char, int, есть ли разница между:

Я бы сказал, вы получите неопределенное поведение. Так что на стабильное поведение рассчитывать не стоит. Вы всегда должны использовать пары new / delete, new [] / delete [] и malloc / free.

1
ответ дан 8 December 2019 в 02:24
поделиться

Хотя может показаться логичным, что вы можете смешивать new [] и free или delete вместо delete [], это делается при условии, что компилятор упрощенным, т.е. он всегда будет использовать malloc () для реализации выделения памяти для new [].

Проблема в том, что если ваш компилятор имеет достаточно умный оптимизатор, он может увидеть, что нет соответствующего "delete []" в новый [] для созданного вами объекта. Следовательно, можно предположить, что он может получить память для него из любого места, включая стек, чтобы сэкономить затраты на вызов реального malloc () для new [].

0
ответ дан 8 December 2019 в 02:24
поделиться

На шаге 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)).

0
ответ дан 8 December 2019 в 02:24
поделиться
Другие вопросы по тегам:

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