Почему Вы записали бы что-то вроде этого? (намеренно не использование удаляет [] на массиве),

Строки являются литералами Python, поэтому ast.literal_eval может анализировать их в байтовые строки Python:

import ast

with open('data.txt') as f:
    for line in f:
        print(ast.literal_eval(line).decode('utf8'))

Вывод:

Afrikaans
አማርኛ
Аҧсшәа
7
задан AstroCB 30 August 2014 в 21:07
поделиться

8 ответов

На самом деле нет смысла писать так и есть серьезная причина никогда не делать этого.

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

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

5
ответ дан 6 December 2019 в 04:51
поделиться

Если вы сделаете это, вы получите то, что стандарт C ++ называет неопределенным поведением - все может случиться.

19
ответ дан 6 December 2019 в 04:51
поделиться

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

8
ответ дан 6 December 2019 в 04:51
поделиться

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

8
ответ дан 6 December 2019 в 04:51
поделиться

Это определенно неправильно, так как new [] должен быть связан с delete []. Если вы этого не сделаете, вы получите неопределенное поведение.

Это может работать (частично), потому что большинство реализаций используют new для реализации new []. Единственное отличие для такой реализации состоит в том, что она будет вызывать только 1 деструктор (для первого элемента вместо всех деструкторов. Но избегайте этого, поскольку это не разрешено c ++ .

5
ответ дан 6 December 2019 в 04:51
поделиться

Теоретически вы должны вызвать delete [].

РЕДАКТИРОВАТЬ: Следующее относится только к Microsoft Visual C ++ (я должен был это сказать).

На практике в Microsoft Visual C ++ не имеет значения, какое удаление вы используете, когда объекты в массиве нет деструкторов. Поскольку у вас есть массив указателей, а указатели не могут иметь деструкторов, вы должны быть в порядке.

Однако, как отмечали другие, некорректно смешивать в C ++ new [] и удалять без []. Хотя в этом случае он может работать в Visual C ++, код не переносим и может не работать в других компиляторах.

Но, возвращаясь к конкретному случаю Visual C ++, даже если вы вызываете delete [], компилятор поймет, что ему не нужно перебирать массив, вызывающий деструкторы, когда это массив примитивных типов, таких как int, символ или указатели. В этом случае вызов delete действительно работает и ничего не сломает. Было бы медленнее делать правильные вещи и вызывать delete [], но и не будет быстрее.

На самом деле, в MSVC ++ delete [] p немедленно вызывает обычный оператор delete (void * p), когда p - указатель на простой тип или тип без деструкторов.

Те, кто мне не верит, переходят через этот код в код CRT для первых двух вызовов delete [].

#include "stdafx.h"
#include <malloc.h>
#include <iostream>
using namespace std;

class NoDestructor
{
    int m_i;
};

class WithDestructor
{
public:
    ~WithDestructor()
    {
        cout << "deleted one WithDestructor at " << (void *) this<< endl;
    }
};

int _tmain(int argc, _TCHAR* argv[])
{
    int **p = new int *[20];
    delete [] p;

    p = (int**) malloc(80);
    free(p);

    NoDestructor *pa = new NoDestructor[20];
    delete [] pa;

    WithDestructor *pb = new WithDestructor[20];
    delete [] pb;

    return 0;
}
2
ответ дан 6 December 2019 в 04:51
поделиться

этот оператор оставит все объекты myClass, на которые указали все указатели в массиве, в памяти. Это также оставляет массив указателей в памяти. Нет никакого способа, который может быть полезен, так как он освобождает только 32 бита памяти, и ОС все еще думает, что у вас есть (размер) myClasses и указатели на каждый из них. Это всего лишь пример того, как программист не убирает себя должным образом.

1
ответ дан 6 December 2019 в 04:51
поделиться

Check with the section [16.11] "How do I allocate / unallocate an array of things?" and beyond in C++ FAQ Lite,

http://www.parashift.com/c++-faq-lite/freestore-mgmt.html#faq-16.11

They explain that the array delete is a must when an array is created.

The instanced of myClass pointed to by the elements of your array should also be deleted where they are created.

1
ответ дан 6 December 2019 в 04:51
поделиться
Другие вопросы по тегам:

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