C ++解除引用Null ptr错误?

时间:2017-04-25 02:12:41

标签: c++ pointers dereference null-pointer

我在张贴之前看过,但如果我的答案在其他地方,请原谅我。作为我的家庭作业的一部分,我需要创建一个指向对象的指针数组(不同类型,但它们共享一个基类)。一旦指针在数组中,我需要能够在它们指向的对象上调用成员函数。我能够为第一个对象执行此操作,但是在我的程序完成循环一次后,我得到以下异常:“0xC0000005:访问冲突执行位置0x00000000”

以下是我的代码。感谢

int main()
{
    Sales * publications[5]; //declare an array of pointers
    for (int i = 0; i < 5; i++) {
        if (i < 3)
            publications[i] = new Book();
        else
            publications[i] = new Tape();
        std::cout << std::endl << publications[i] << std::endl;
        (*publications)[i].readData();
        (*publications)[i].displayData();
    }

    for (int i = 0; i < 5; i++) { //delete the array to avoid memory leak
        delete publications[i];
    }

    std::cout << std::endl;
    system("pause");
    return 0;
}

我已经测试了readData和displayData函数,它们工作正常。

2 个答案:

答案 0 :(得分:2)

此:

(*publications)[i].readData();

应该是:

publications[i]->readData();

答案 1 :(得分:2)

publications是一个指针数组。

(*publications)[i].readData();

在此代码段中,操作顺序不正常。由于括号,*解除引用运算符将​​优先于[]数组语法运算符。

将要发生的第一件事是publications(数组)将被取消引用 - 而不是位于索引i的元素。这将始终为您提供数组中的第一个元素,因为数组变量只是第一个元素的地址。

发生的第二个操作是将字节偏移量(sizeof(Sales) * i))添加到取消引用返回的内存地址中。当索引i为0时,这不是问题,因为没有要添加的偏移量,并且在计算的内存位置存在对象。但是,一旦索引不等于0,计算的内存地址就不会指向有效的Sales对象,因此您可能会崩溃,也可能不会崩溃,具体取决于内存位置的实际位置。

使用给定运算符的正确操作顺序是:

(*(publications[i])).readData();

首选使用->运算符:

publications[i]->readData();

现在,[]数组语法运算符优先,将数组的地址偏移到数组中的元素,然后*.->用于取消引用元素的指针,如预期的那样到达对象。