我在张贴之前看过,但如果我的答案在其他地方,请原谅我。作为我的家庭作业的一部分,我需要创建一个指向对象的指针数组(不同类型,但它们共享一个基类)。一旦指针在数组中,我需要能够在它们指向的对象上调用成员函数。我能够为第一个对象执行此操作,但是在我的程序完成循环一次后,我得到以下异常:“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函数,它们工作正常。
答案 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();
现在,[]
数组语法运算符优先,将数组的地址偏移到数组中的元素,然后*.
或->
用于取消引用元素的指针,如预期的那样到达对象。