在数组中重载new和delete

时间:2013-08-24 06:52:01

标签: c++

我正在编写一个程序,用于在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() 当我厌倦了程序被绞死。

3 个答案:

答案 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只是一个变量,没有这样的对象,因此结果是未定义的。 (你很幸运它被绞死了:在最坏的情况下,你会得到一个看起来正确的随机结果,从而隐藏错误!)。

在您的具体情况下,ip2(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(而不是悬空指针)。