Строки являются литералами 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
አማርኛ
Аҧсшәа
На самом деле нет смысла писать так и есть серьезная причина никогда не делать этого.
Это правда, что для типов с тривиальными деструкторами (такими как необработанные указатели в вашем случае) нет необходимости знать фактическое количество элементов в массиве, и поэтому компилятор может решить отобразить new [] и delete [] на new и delete , чтобы уменьшить накладные расходы. Если он решит таким образом, вы не сможете остановить его без дополнительных шагов, поэтому оптимизация компилятора будет выполняться без вашего уведомления и будет бесплатной.
В то же время кто-то, использующий ваш код, может захотеть перегрузить глобальные операторы новые и удаляют (и новые [] и удаляют [] также).
Если вы сделаете это, вы получите то, что стандарт C ++ называет неопределенным поведением - все может случиться.
Это утечка памяти. new []
должен соответствовать delete []
. Кроме того, поскольку таблица
является указателем на первый элемент массива указателей, любой член массива, если он сам по себе является массивом, должен быть удален с помощью delete []
.
Мало того, что в этом нет никакой пользы, код просто неверен - в лучшем случае, он приводит к утечке памяти, а в худшем случае, он может привести к сбою вашей программы или открыть труднодоступные места. дыра в безопасности. Вы всегда должны сопоставлять new
с delete
и new []
с delete []
. Всегда.
Это определенно неправильно, так как new [] должен быть связан с delete []. Если вы этого не сделаете, вы получите неопределенное поведение.
Это может работать (частично), потому что большинство реализаций используют new для реализации new []. Единственное отличие для такой реализации состоит в том, что она будет вызывать только 1 деструктор (для первого элемента вместо всех деструкторов. Но избегайте этого, поскольку это не разрешено c ++ .
Теоретически вы должны вызвать 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;
}
этот оператор оставит все объекты myClass, на которые указали все указатели в массиве, в памяти. Это также оставляет массив указателей в памяти. Нет никакого способа, который может быть полезен, так как он освобождает только 32 бита памяти, и ОС все еще думает, что у вас есть (размер) myClasses и указатели на каждый из них. Это всего лишь пример того, как программист не убирает себя должным образом.
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.