Беда следующая: работаю со списком в классе(Использование STL запрещено) худо бедно расписал методы. Далее когда описываю экземпляр в main и пытаюсь вызвать метод addElement возникает ошибка доступа к памяти. Как быть? Из-за чего так происходит?
Листинг main.cpp
#include "stdafx.h"
#include "vset.h"
#include <iostream>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
vset a;
a.AddElement(&a.ilast, 5);
// a.AddElement(&a.last, 7);
a.PrintList(a.ihead);
return 0;
}
Листинг реализации класса vset.cpp
#pragma once
#include "vset.h"
#include <iostream>
using namespace std;
vset::SingleList * vset::makeFirst(int d)
{
SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = 0; cRec->prev = 0;
return cRec;
}
void vset::AddElement(vset::SingleList **last, int d)
{
vset::SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = 0; cRec->prev = *last;
(*last)->next = cRec;
*last = cRec;
}
vset::SingleList * vset::search(SingleList * const pbeg, int d)
{
SingleList *cRec = pbeg;
while (cRec)
{
if (cRec->Data == d)break;
cRec = cRec->next;
}
return cRec;
}
bool vset::remove(vset::SingleList **head, vset::SingleList **last, int key)
{
if (SingleList *pkey = search(*head, key))
{
if (pkey == *head)
{
*head = (*head)->next;
(*head)->prev = 0;
}
else if (pkey == *last)
{
*last = (*last)->prev;
(*last)->next = 0;
}
else {
(pkey->prev)->next = pkey->next;
(pkey->next)->prev = pkey->prev;
}
delete pkey;
return true;
}
return false;
}
vset::SingleList * vset::insert(vset::SingleList * const head, vset::SingleList **last, int key, int d)
{
if (SingleList *pkey = search(head, key))
{
SingleList *cRec = new SingleList;
cRec->Data = d; cRec->next = pkey->next;
cRec->prev = pkey; pkey->next = cRec;
if (pkey != *last) (cRec->next)->prev = cRec;
else *last = cRec;
return cRec;
}
return 0;
}
void vset::PrintList(vset::SingleList * const head)
{
SingleList *cRec = head;
while (cRec)
{
cout << cRec->Data << " ";
cRec = cRec->next;
}
}
void getData()
{
}
vset::vset()
{
SingleList *ihead = makeFirst(0);
SingleList *ilast = ihead;
// getLast(&last);
}
vset::vset(int d)
{
SingleList *ihead = makeFirst(d);
SingleList *ilast = ihead;
}
/*vset::SingleList getLast(vset::SingleList **last)
{
static vset::SingleList **olast;
if (!last) olast = last;
return **olast;
}*/
vset::~vset()
{
}
Интерфейс vset.h
#pragma once
class vset
{
public:
struct SingleList
{
int Data;
SingleList *next;
SingleList *prev;
};
SingleList *ihead;
SingleList *ilast;
public:
vset();
vset::vset(int d);
~vset();
SingleList * makeFirst(int d);
void AddElement(SingleList **last, int d);
SingleList * search(SingleList * const pbeg, int d);
bool remove(SingleList **head, SingleList **last, int key);
SingleList * insert(SingleList * const head, SingleList **last, int key, int d);
void PrintList(SingleList * const head);
void getData();
vset::SingleList getLast(vset::SingleList);
};
Начнем исправление ошибок:)
#pragma once в cpp классе? серьезно?vset::vset(int d); - вот так в объявлении класса не нужно писать. Правильно писать вот так vset(int d);или ещё лучше так explicit vset(int d);Ошибки в конструкторе-деструкторе
vset::vset()
{
SingleList *ihead = makeFirst(0);
SingleList *ilast = ihead;
// getLast(&last);
}
Здесь объявлены указатели, имя которых пересекается с переменными класса. По выходу с конструктора эти указатели потеряются, а значение переменных класса так и останется неинициализированным. Правильно конструктор писать где то так
vset::vset()
{
ihead = makeFirst(0);
ilast = ihead;
}
После этого код как минимум уже запускается и работает как нужно.
Но в нем есть ещё утечка - в деструкторе не освобождается память. По хорошему можно написать функцию clear, которая будет очищать содержимое и просто вызывать ее в деструкторе.
Но есть ещё пару замечаний. Функция AddElement требует указателя на последний элемент. Если ей передать просто указатель на произвольный элемент, то она испортит список. (будет как бы вилка). Поэтому, лучше этот параметр оттудова совсем убрать.
Также функции у Вас названы в разнобой. Есть и маленькими буквами, и CamelCase, и camelCase. Приведите все к одному виду.
Как развивать веб-проекты в 2026 году: технологии, контент E-E-A-T и факторы доверия
Современные инструменты для криптотрейдинга: как технологии помогают принимать решения
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники