Хотя этот популярный ответ даст вам желаемый синтаксис индексации, он вдвойне неэффективен: большой и медленный как в пространстве, так и во времени.
Почему этот ответ большой и медленный
Предлагаемое решение состоит в создании динамического массива указателей, а затем инициализации каждого указателя на собственный независимый динамический массив. Преимущество этого подхода состоит в том, что он дает вам синтаксис индексации, к которому вы привыкли, поэтому, если вы хотите найти значение матрицы в позиции x, y, вы скажете:
int val = matrix[ x ][ y ];
работает, потому что матрица [x] возвращает указатель на массив, который затем индексируется с помощью [y]. Разрушение:
int* row = matrix[ x ];
int val = row[ y ];
Удобно, да? Нам нравится наш синтаксис [x] [y].
Но решение имеет большой недостаток, который заключается в том, что он как жирный, так и медленный.
Почему?
Причина, по которой это как жир, так и медленный, на самом деле то же самое. Каждая «строка» в матрице представляет собой отдельно распределенный динамический массив. Создание распределения кучи является дорогостоящим как во времени, так и в пространстве. Распределитель занимает время, чтобы сделать выделение, иногда выполняя алгоритмы O (n), чтобы сделать это. И распределитель «прокладывает» каждый из ваших массивов строк с дополнительными байтами для бухгалтерии и выравнивания. Это дополнительное пространство стоит ... ну ... дополнительное пространство. Освобождение будет также взять дополнительное время, когда вы идете на освобождение матрицы, тщательно освобождая каждое выделение каждой строки. Получает меня в поту, просто думая об этом.
Есть еще одна причина, по которой это медленно. Эти отдельные распределения, как правило, живут в прерывистых частях памяти. Одна строка может быть по адресу 1000, другая по адресу 100 000 - вы получите эту идею. Это означает, что когда вы проходите матрицу, вы прыгаете через память, как дикий человек. Это, как правило, приводит к промахам в кеше, которые значительно замедляют время обработки.
Итак, если вы абсолютный должен иметь свой симпатичный синтаксис [x] [y], используйте это решение. Если вы хотите быстроту и малость (и если вам все равно, почему вы работаете на C ++?), Вам нужно другое решение.
Другое решение
Лучшее решение состоит в том, чтобы выделить всю вашу матрицу в виде единого динамического массива, а затем использовать (слегка) умную математическую индексацию для доступа к ячейкам. Матрица индексирования только немного умна; nah, это не умно: это очевидно.
class Matrix
{
...
size_t index( int x, int y ) const { return x + m_width * y; }
};
Учитывая эту функцию index()
(которую я представляю, является членом класса, потому что он должен знать m_width
вашего матрица), вы можете получить доступ к ячейкам в матричном массиве. Матричный массив выделяется следующим образом:
array = new int[ width * height ];
Таким образом, эквивалент этого в медленном, жирном решении:
array[ x ][ y ]
... это в быстрой, малой Решение:
array[ index( x, y )]
Грустный, я знаю. Но вы привыкнете к этому. И ваш процессор поблагодарит вас.
Проблема строка с в Вашей структуре. Я нашел, что маршалинг типов как байт/закорачивать/интервал не является проблемой; но когда необходимо упорядочить в составной тип, такой как строка, Вам нужна Ваша структура для явной имитации неуправляемого типа. Можно сделать это с MarshalAs attrib.
Для Вашего примера, следующее должно работать:
[StructLayout(LayoutKind.Explicit)]
struct StructType
{
[FieldOffset(0)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string FileDate;
[FieldOffset(8)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 8)]
public string FileTime;
[FieldOffset(16)]
public int Id1;
[FieldOffset(20)]
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 66)] //Or however long Id2 is.
public string Id2;
}
У меня не было удачи с помощью BinaryFormatter, я предполагаю, что у меня должна быть полная структура, которая соответствует содержанию файла точно. Я понял, что в конце не интересовался многим содержания файла так или иначе, таким образом, я пошел с решением чтения части потока в bytebuffer и затем преобразование его с помощью
Encoding.ASCII.GetString()
для строк и
BitConverter.ToInt32()
для целых чисел.
я должен буду быть в состоянии проанализировать больше файла позже, но для этой версии мне сошли с рук просто несколько строк кода.
Я не вижу проблемы с Вашим кодом.
только из моей головы, что, при попытке сделать это вручную? это работает?
BinaryReader reader = new BinaryReader(stream);
StructType o = new StructType();
o.FileDate = Encoding.ASCII.GetString(reader.ReadBytes(8));
o.FileTime = Encoding.ASCII.GetString(reader.ReadBytes(8));
...
...
...
также попытка
StructType o = new StructType();
byte[] buffer = new byte[Marshal.SizeOf(typeof(StructType))];
GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
Marshal.StructureToPtr(o, handle.AddrOfPinnedObject(), false);
handle.Free();
тогда использование буфер [] в Вашем BinaryReader вместо того, чтобы считать данные с FileStream, чтобы видеть, получаете ли Вы все еще исключение AccessViolation.
у меня не было удачи с помощью BinaryFormatter, я предполагаю, что у меня должна быть полная структура, которая соответствует содержанию файла точно.
, Который имеет смысл, BinaryFormatter имеет свой собственный формат данных, абсолютно несовместимый с Вашим.
Чтение прямо в структуры является злым - много программ C упали из-за различных порядков байтов, различных реализаций компилятора полей, упаковки, размера слова.......
Вы являетесь лучшими из сериализации и десериализации байта байтом. Используйте сборку в материале, если Вы хотите или просто привыкаете к BinaryReader.
Попробуйте это:
using (FileStream stream = new FileStream(fileName, FileMode.Open))
{
BinaryFormatter formatter = new BinaryFormatter();
StructType aStruct = (StructType)formatter.Deserialize(filestream);
}
Как сказал Ронни, я бы использовал BinaryReader и прочитал каждое поле отдельно. Я не могу найти ссылку на статью с этой информацией, но было замечено, что использование BinaryReader для чтения каждого отдельного поля может быть быстрее, чем Marshal.PtrToStruct, если структура содержит менее 30-40 полей или около того. Ссылку на статью выложу, когда найду.
Ссылка на статью находится по адресу: http://www.codeproject.com/Articles/10750/Fast-Binary-File-Reading-with-C
При маршалинге массива структур PtrToStruct получает быстрее, потому что вы можете думать о количестве полей как о полях * длина массива.