#c_sharp #указатели
Добрый день! Требуется создать связный список объектов структуры, в котором текущий элемент должен указывать на следующий, последний - на null. На C++ когда делал подобное - проблем не возникло. На C# первый элемент создается без проблем. Но второй создается с тем-же адресом! Как это исправить? // Структура объектов очереди struct QueueItem { public int Value; public unsafe QueueItem* Next; public unsafe QueueItem(int value) : this() { Value = value; Next = null; } } class QueueWithMinStats { private unsafe QueueItem* _first; private unsafe QueueItem* _last; public unsafe QueueWithMinStats() { _first = null; _last = null; } // Добавить в очередь значение public unsafe void Enqueue(int value) { // Проблема тут!!! var newItem = new QueueItem(value); var newItemLink = &newItem; if (_first == null) // Если вводимый элемент - первый _first = newItemLink; else _last->Next = newItemLink; _last = newItemLink; } }
Ответы
Ответ 1
Применительно к структуре, оператор new не выделяет память, а лишь вызывает конструктор. Сама структура каждый раз создается на стеке в одном и том же месте - неудивительно что указатели одинаковы. Для того, чтобы структура "перенеслась" в кучу - надо кастануть ее к типу object (эта операция называется упаковкой). Но у упакованной структуры получить адрес средствами языка - не так-то и просто... Поэтому предлагаю вам сделать все по-другому. Во-первых, замените структуру на класс (значимый тип на ссылочный). Во-вторых, уберите указатели: для ссылочных типов они не нужны. Вместе с другими, не столь критичными, исправлениями, получится как-то так: class QueueWithMinStats { class QueueItem // я перенес этот класс внутрь, потому что за пределами реализации очереди он никому не должен быть интересен { public int Value; public QueueItem Next; public QueueItem(int value) { Value = value; // Next инициализаровать не надо - поля классов инициализируются значениями по умолчанию автоматически } } private QueueItem _first; private QueueItem _last; // Конструктор пока не нужен public void Enqueue(int value) { // Проблемы больше нет!!! var newItem = new QueueItem(value); // Переменная newItemLink больше не нужна - потому что QueueItem - это ссылочный тип if (_first == null) // Если вводимый элемент - первый _first = newItem; else _last.Next = newItem; _last = newItem; } }
Комментариев нет:
Отправить комментарий