我正在编写一个程序,用于在c ++中使用Arrays重载new和delete。这是代码
#include <iostream>
#include <cstdlib>
#include <new>
using namespace std;
class loc {
int longitude, latitude;
public:
loc() {longitude = latitude = 0;}
loc(int lg, int lt) {
longitude = lg;
latitude = lt;
}
void show() {
cout << longitude << " ";
cout << latitude << "\n";
}
void *operator new(size_t size);
void operator delete(void *p);
void *operator new[](size_t size);
void operator delete[](void *p);
};
// new overloaded relative to loc.
void *loc::operator new(size_t size)
{
void *p;
cout << "In overloaded new.\n";
p = malloc(size);
if(!p) {
bad_alloc ba;
throw ba;
}
return p;
}
// delete overloaded relative to loc.
void loc::operator delete(void *p)
{
cout << "In overloaded delete.\n";
free(p);
}
// new overloaded for loc arrays.
void *loc::operator new[](size_t size)
{
void *p;
cout << "Using overload new[].\n";
p = malloc(size);
if(!p) {
bad_alloc ba;
throw ba;
}
return p;
}
// delete overloaded for loc arrays
void loc::operator delete[](void *p)
{
cout << "Freeing array using overloaded delete[]\n";
free(p);
}
int main()
{
loc *p1, *p2;
int i;
try {
p1 = new loc (10, 20); // allocate an object
} catch (bad_alloc xa) {
cout << "Allocation error for p1.\n";
return 1;;
}
try {
p2 = new loc [10]; // allocate an array
} catch (bad_alloc xa) {
cout << "Allocation error for p2.\n";
return 1;;
}
p1->show();
for(i=0; i<10; i++)
p2[i].show();
delete p1; // free an object
delete [] p2; // free an array
return 0;
}
在主要的p2[i].show();
行中。为什么我们使用“。”。而不是“ - &gt;”。答案是它变成了数组吗?是真的吗?
我们可以将指针说成p3到指针p2吗?
像宣布
loc *p1,*p2,**p3;
p3=&p2;
但接下来我们将如何通过p3显示结果。我们会显示p3[i]->show()
当我厌倦了程序被绞死。
答案 0 :(得分:1)
我们应该显示
p3[i]->show()
吗?
没有。在此行中,您尝试访问p3 + i
内存地址。这会导致未定义的行为。你应该使用
(*p3)[i].show()
如果p3[i]->show()
拥有指针,则应使用p3[i]
。
答案 1 :(得分:1)
不完全是。数组是一个接一个地存储的相同类型对象的序列。 “对象地址”中的指针。
你观察到的巧合是两个事实的结果:
T& operator[](T* p, int i)
由编译器本身实现为return *(p+i);
因此,无论您存储一系列相同的对象,并且您有一个起始地址,[]运算符都会引导您进入第i个对象。并且由于数组的起始地址是第一个元素的地址,并且是通过隐式数组到指针转换获得的,因此您会观察到两个表达式的实质重合。
但巧合就在那里停止了。
关于指向指针,请确保您完全理解这个概念:按照您的要求,不清楚是否:
Jut更清楚:
int a[5] = { 10,11,12,13,14 }; //5 integer named "a"
int* p = a; // p points to a[0], hence *p and p[0] gives 10, p[1] give 11
int* q = p+1; // q points to one after p (hence to 11), *q and q[0] are 11, q[1] 12 ...
int** d = &p; // d points to p, hence **d is 10 (*d)[1] 11 etc.
您观察到的问题是d[3]
不是整数13,而是int*
之后的p
d
指向的p
。但是p3[i]->show
只是一个变量,没有这样的对象,因此结果是未定义的。 (你很幸运它被绞死了:在最坏的情况下,你会得到一个看起来正确的随机结果,从而隐藏错误!)。
在您的具体情况下,i
在p2
(p3指向的内容)之后将偶然存储在内存pointer to loc
指针中的值视为show
并尝试在该随机地址执行假定loc
对象的show
方法,很可能不属于您的程序存储空间,因此longitude
无法访问{{1}}本地变量
结果 - 基本上 - 全部取决于p3 [i]中存在的随机数据。
答案 2 :(得分:0)
为什么我们使用“。”。而不是“ - &gt;” ?答案是它变成了阵列吗?
因为p2 [i]实际上是loc的一个实例而不是指向loc的指针; "loc *p2"
p2是指向loc的指针,而不是数组,它不会成为数组。
我们可以将指针说成p3到指针p2吗?
是的,这是合法的。但是在你的真实世界项目中首先初始化p2(而不是悬空指针)。