Как мог, соединяясь новый [] с, удаляют возможно вывод к утечке памяти только?

Я постараюсь ответить на ваш вопрос один за другим.

Разве мы не считаем, что wild card like (Collection<? extends E> c); также поддерживает тип полиморфизма?

№. Причина в том, что ограниченный подстановочный символ не имеет определенного типа параметра. Это неизвестно. Все это «знает», что «сдерживание» относится к типу E (независимо от того, что определено). Таким образом, он не может проверить и обосновать, соответствует ли предоставленное значение ограниченному типу.

Таким образом, не имеет смысла иметь полиморфное поведение в подстановочных знаках.

Документ обескураживает второй объявления и способствует использованию первого синтаксиса? В чем разница между первой и второй декларацией?

Первый вариант лучше в этом случае, так как T всегда ограничен, а source обязательно будет иметь значения (неизвестных), что подклассы T.

Итак, предположим, что вы хотите скопировать весь список чисел, первая опция будет

Collections.copy(List<Number> dest, List<? extends Number> src);

src, по существу, может принять List<Double> , List<Float> и т. д., так как существует верхняя граница параметризованного типа, найденная в dest.

Второй вариант заставит вас привязать S для каждого типа, который вы хотите скопировать, например поэтому

//For double 
Collections.copy(List<Number> dest, List<Double> src); //Double extends Number.

//For int
Collections.copy(List<Number> dest, List<Integer> src); //Integer extends Number.

Поскольку S является параметризованным типом, который требует привязки.

Надеюсь, это поможет.

26
задан Kevin Panko 19 December 2009 в 01:43
поделиться

9 ответов

Suppose I'm a C++ compiler, and I implement my memory management like this: I prepend every block of reserved memory with the size of the memory, in bytes. Something like this;

| size | data ... |
         ^
         pointer returned by new and new[]

Note that, in terms of memory allocation, there is no difference between new and new[]: both just allocate a block of memory of a certain size.

Now how will delete[] know the size of the array, in order to call the right number of destructors? Simply divide the size of the memory block by sizeof(T), where T is the type of elements of the array.

Now suppose I implement delete as simply one call to the destructor, followed by the freeing of the size bytes, then the destructors of the subsequent elements will never be called. This results in leaking resources allocated by the subsequent elements. Yet, because I do free size bytes (not sizeof(T) bytes), no heap corruption occurs.

29
ответ дан 28 November 2019 в 06:32
поделиться

Почему не может быть ответа, что он вызывает и то и другое?

Очевидно, что память просочилась, происходит ли повреждение кучи или нет.

Вернее, поскольку я могу заново реализовать новое и удалить ..... не может ли это вообще ничего не вызывать. Технически я могу вызвать новое и удалить, чтобы выполнить новое [] и удалить [].

HENCE: неопределенное поведение.

2
ответ дан Lee Louviere 15 October 2019 в 07:27
поделиться

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

4
ответ дан 28 November 2019 в 06:32
поделиться

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

В некоторых случаях это может вызвать гораздо более серьезные ошибки.

3
ответ дан 28 November 2019 в 06:32
поделиться

Кажется, действительно ваш вопрос: «Почему не происходит повреждения кучи?». Ответ на этот вопрос - «потому что диспетчер кучи отслеживает размеры выделенных блоков». Вернемся на минуту к C: если вы хотите выделить один int в C, вы должны сделать int * p = malloc (sizeof (int)) , если вы хотите выделить массив размером ] n вы можете написать int * p = malloc (n * sizeof (int)) или int * p = calloc (n, sizeof (int)) . Но в любом случае вы его освободите бесплатно (p) , независимо от того, как вы его распределили. Вы никогда не передаете размер в free (), free () просто «знает», сколько нужно освободить, потому что размер блока malloc () - ed сохраняется где-то «перед» блоком. Вернемся к C ++, new / delete и new [] / delete [] обычно реализуются в терминах malloc (хотя они и не должны быть такими, вам не следует полагаться на это). Вот почему комбинация new [] / delete не повреждает кучу - удаление освобождает нужный объем памяти, но, как объясняли все до меня, вы можете получить утечки, не вызывая нужное количество деструкторов.

Тем не менее, рассуждения о неопределенном поведении в C ++ всегда бессмысленны. Почему это важно, если комбинация new [] / delete работает, "только" утекает или вызывает повреждение кучи? Вы не должны так кодить, точка! И на практике я бы по возможности избегал ручного управления памятью - STL и ускорение существуют не просто так.

Вот почему комбинация new [] / delete не повреждает кучу - удаление освобождает нужный объем памяти, но, как объясняли все до меня, вы можете получить утечки, не вызывая нужное количество деструкторов.

Тем не менее, рассуждения о неопределенном поведении в C ++ всегда бессмысленны. Почему это важно, если комбинация new [] / delete работает, "только" утекает или вызывает повреждение кучи? Вы не должны так кодить, точка! И на практике я бы по возможности избегал ручного управления памятью - STL и ускорение существуют не просто так.

Вот почему комбинация new [] / delete не повреждает кучу - удаление освобождает нужный объем памяти, но, как объясняли все до меня, вы можете получить утечки, не вызывая нужное количество деструкторов.

Тем не менее, рассуждения о неопределенном поведении в C ++ всегда бессмысленны. Почему это важно, если комбинация new [] / delete работает, "только" утекает или вызывает повреждение кучи? Вы не должны так кодить, точка! И на практике я бы по возможности избегал ручного управления памятью - STL и ускорение существуют не просто так.

рассуждения о неопределенном поведении в C ++ всегда бессмысленны. Почему это важно, если комбинация new [] / delete работает, "только" утекает или вызывает повреждение кучи? Вы не должны так кодить, точка! И на практике я бы по возможности избегал ручного управления памятью - STL и ускорение существуют не просто так.

рассуждения о неопределенном поведении в C ++ всегда бессмысленны. Почему это важно, если комбинация new [] / delete работает, "только" утекает или вызывает повреждение кучи? Вы не должны так кодить, точка! И на практике я бы по возможности избегал ручного управления памятью - STL и ускорение существуют не просто так.

7
ответ дан 28 November 2019 в 06:32
поделиться

Утечка памяти может произойти, если оператор new () переопределен, а оператор new [] - нет. то же самое относится к оператору удаления / удаления []

3
ответ дан 28 November 2019 в 06:32
поделиться

Помимо неопределенного поведения, наиболее очевидная причина утечек заключается в том, что реализация не вызывает деструктор для всех, кроме первого объекта в массиве. Это, очевидно, приведет к утечкам, если объектам выделены ресурсы.

Это простейший из возможных классов, о которых я мог думать, приводя к такому поведению:

 struct A { 
       char* ch;
       A(): ch( new char ){}
       ~A(){ delete ch; }
    };

A* as = new A[10]; // ten times the A::ch pointer is allocated

delete as; // only one of the A::ch pointers is freed.

PS: обратите внимание, что конструкторы не вызываются во многих других ошибках программирования, тоже: невиртуальные деструкторы базового класса, ложная зависимость от интеллектуальных указателей, ...

3
ответ дан 28 November 2019 в 06:32
поделиться

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

Наиболее вероятное объяснение этой чуши о "утечке памяти" состоит в том, что с невинно наивной точки зрения разница между delete и delete [] заключается в том, что delete используется для уничтожения только одного объекта, а delete [] уничтожает массив объектов («множество» объектов). Наивный вывод, который обычно делается из этого, заключается в том, что первый элемент массива будет уничтожен delete , в то время как остальные останутся, таким образом создавая предполагаемую «утечку памяти». Конечно, любой программист, имеющий хотя бы базовое представление о типичных реализациях кучи, сразу поймет, что наиболее вероятным последствием этого является повреждение кучи, а не «утечка памяти».

Другое популярное объяснение наивной теории «утечки памяти» состоит в том, что поскольку вызывается неправильное количество деструкторов, вторичная память, принадлежащая объектам в массиве, не освобождается. Это может быть правдой, но это, очевидно, очень вынужденное объяснение, которое не имеет большого значения перед лицом гораздо более серьезной проблемы с повреждением кучи.

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

Излишне добавлять, новый / удалить и новый [] / delete [] на самом деле два независимых механизма управления памятью, которые можно настраивать независимо. После того, как они будут настроены (путем замены необработанных функций управления памятью), нет абсолютно никакого способа даже начать предсказывать, что может случиться, если они смешаются.

12
ответ дан 28 November 2019 в 06:32
поделиться

Поздно для ответа, но ...

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

3
ответ дан 28 November 2019 в 06:32
поделиться
Другие вопросы по тегам:

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