C ++ «Ошибка шины: 10» и работа с указателями

Я выполняю упражнение Data Structures, и со вчерашнего дня я был заблокирован из-за ошибки шины, которую я считаю, потому что я делаю плохие вещи с памятью. Но я не могу понять, что именно.

Это требования, которые я установил для практики:

  • возможность добавить товар (любым способом) в список
  • возможность получить товар в списке в текущей позиции (next, prev, moveToStart, moveToEnd… есть указатель курсора, который здесь называется «актуальный»)
  • любые изменения, которые я делаю в извлеченном продукте, должны быть обновлены в структуре данных (т.е. list :: retrieve (* product), product-> посещения ++)

Это код, который у меня есть. Извиняюсь за имена var, я должен сделать это на испанском и поэтому имена на испанском.

class producto { // My product
public:
string marca;
double precio;
int visitas;
int compras;

producto () {}
producto (string M, double P, int V = 0, int C = 0) : marca(M), precio(P), visitas(V), compras(C) {}
};

class nodo {
public:
producto valor; // value
nodo *siguiente; // next
nodo *anterior; // prev

nodo (producto P, nodo *A = NULL, nodo *S = NULL) : valor(P), anterior(A), siguiente(S) {}
};

class lista {
private:
nodo *inicio;
nodo *final;
nodo *actual;

public:
lista();
bool esta_vacia(); // is empty?
bool es_final(); // is the end?
int insertar(producto p); // insert given p
void moverPrincipio(); // "move to beginning"void siguiente(); // "next"void imprimir(); // "print"int leer(producto *p); // read, return 0 or 1 if successful, return product by ref
};

lista::lista() {
this->inicio = NULL;
this->final = NULL;
this->actual = NULL;
}

bool lista::esta_vacia() {
return (this->inicio == NULL);
}

bool lista::es_final() {
return (this->actual == NULL);
}

void lista::moverPrincipio() {
this->actual = this->inicio;
}

void lista::siguiente() {
if(!this->es_final()) {
this->actual = this->actual->siguiente;
}
}

void lista::imprimir() {
int i = 1;
producto *p;
this->moverPrincipio();

while(!this->es_final()) {
if(this->leer(p) == 0) {
cout << i << ".- ##" << p->marca << "##, Views ##" << p->visitas << "##\n";
p->visitas++;
i++;
this->siguiente();
}
}
}

int lista::leer(producto *p) {
if(this->actual != NULL) {
*p = this->actual->valor;

return 0;
} else {
return 1;
}
}

int lista::insertar(producto p) {
if(this->esta_vacia()) {
nodo *tmp = new nodo(p);
this->inicio = tmp;
this->final = this->inicio;
} else {
nodo *tmp = new nodo(p, this->final);
this->final->siguiente = tmp;
this->final = tmp;
}

return 0;
}

Я удалил ненужный код. Вот как я его использую (и терпит неудачу):

lista *productos = new lista();

productos->insertar(producto("Shoes", 19.90));
productos->insertar(producto("Socks", 25.00));

// I should expect views = 0
productos->imprimir();

// But now, views = 1
productos->imprimir();

При выполнении единственное, что я получаю, это «Ошибка шины: 10» при первом выполнении imprimir («print»). Вставка работает без ошибок (но что-то там тоже может быть не так).

Моя идея заключается в том, чтобы держать продукт внутри узла и указывать ссылку на его местоположение при его возврате, чтобы любые изменения также отражались там (например, увеличение представления или счетчика покупок для извлеченного элемента отражает изменение при чтении). список позже).

Я был бы чрезвычайно благодарен, если бы кто-то мог указать на ошибки, которые я делаю здесь.

Спасибо!!

ОБНОВИТЬ Вот скомпилированный пример.

0

Решение

Вы передаете указатель на lista::leer и вы хотите написать значение для него. Вы будете писать в нераспределенной памяти. Вероятно, вы хотели указатель на actual элемент.

Прежде всего, вам нужно изменить подпись:

int lista::leer(producto **p);

обратите внимание на двойную звезду, так как мы будем писать сам указатель.

Затем вы должны назначить указатель в actual->valor к этому в lista::leer:

*p = &(this->actual->valor);

Наконец, вы должны передать указатель на p в lista::imprimir:

 if(this->leer(&p) == 0) {
// ...
}

Или вы можете изменить lista::leer вернуть указатель и проверить, если это nullptr/NULL,

1

Другие решения