C++ "Bus error: 10"和使用指针

标签 c++ pointers bus-error

我正在做一个数据结构练习,从昨天开始我就因为一个总线错误而被阻塞了,我认为这是因为我在用内存做坏事。但我无法弄清楚到底是什么。

这些是我为实践制定的要求:

  • 能够将产品添加到列表中(任何方式都可以)
  • 能够在当前位置检索列表中的产品(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)稍后阅读列表时更改)。

如果有人能指出我在这里犯的错误,我将不胜感激。

谢谢!!

更新 Here's a compilable example .

最佳答案

您将一个指针传递给 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/

相关文章:

c - 排序的双向链表在反向访问时给出总线错误

c++ - 有没有办法不继承子类中函数的 "virtualness"?

c++ - 如何在运行时检查类型?

c++ - 在不使用 decltype[c++] 的情况下传递键类型的比较函数

c - 指向数组解引用的指针

fortran - 程序接收信号 SIGBUS : Access to an undefined portion of a memory object

c++ - 如何从值元组创建左值引用元组

c++ - 调试 "crashed"最上面的窗口

c - 由 2 个结构组成的链表。接入节点

使用 mmap 将整个文件复制到内存中