我正在做一个数据结构练习,从昨天开始我就因为一个总线错误而被阻塞了,我认为这是因为我在用内存做坏事。但我无法弄清楚到底是什么。
这些是我为实践制定的要求:
- 能够将产品添加到列表中(任何方式都可以)
- 能够在当前位置检索列表中的产品(next, prev, moveToStart, moveToEnd ...有光标指针,这里称为“actual”)
- 我对检索到的产品所做的任何更改都应该在数据结构中更新(即 list::retrieve(*product), product->visits++)
这是我的代码。对 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(“打印”)时。插入工作没有错误(但也可能有问题)。
我的想法是将产品保存在节点内,并在返回时给出其位置的引用,以便任何更改也反射(reflect)在那里(例如,增加检索元素的查看或购买计数器,反射(reflect)稍后阅读列表时更改)。
如果有人能指出我在这里犯的错误,我将不胜感激。
谢谢!!
最佳答案
您将一个指针传递给 lista::leer
并且您想要向其写入一个值。您将写入未分配的内存。可能,您想要的是指向 actual
元素的指针。
首先需要修改签名:
int lista::leer(producto **p);
注意双星,因为我们将编写指针本身。
然后,您必须在 lista::leer
中为它分配一个 指针 到 actual->valor
:
*p = &(this->actual->valor);
最后,你必须在 lista::imprimir
中传递一个指向 p
的指针:
if(this->leer(&p) == 0) {
// ...
}
或者,您可以修改 lista::leer
以返回一个指针并检查它是否为 nullptr
/NULL
。
关于C++ "Bus error: 10"和使用指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27331469/