为什么非初始化的类对象指针可以访问指针成员,而struct指针则无法访问指针变量

时间:2016-07-23 08:12:24

标签: c++ class pointers struct

在下面的程序中,指针变量可以通过非初始化的类对象访问,但不能通过非初始化的结构指针访问(导致分段错误)??

#include<iostream>
#include<cstdio>
using namespace std;
//structure demo
struct demo
{
  int *data;
};
//class ABC
class ABC
{
    public:
   int *A;
   //default constructor 
    ABC()
   {
     cout<<"ABC constructor\n";

   }
  //display function..
  void displayA()
  {
    printf("display A\n");
  }


};

int main()
{
  ABC *obj;  //class object pointer..
  struct demo *DEMO;  //structure pointer

  printf("%u\n",obj->A);  //works properly no segmentation fault
  printf("%u\n", DEMO->data); // leading to segmentation fault..

  return 0;
}

我编译并运行上面的程序

g++ -o p1 p1.cpp 
./p1  
**Output:**
1831469976
Segmentation fault (core dumped)

根据我的分析,任何指针只有基于体系结构(32位或64位......)的字大小的内存。因此,类对象指针将具有指针的内存而不是其数据成员。那么,非初始化类对象指针(obj)如何能够访问其数据成员(A),因为它没有内存。

还有一件事我想问一下存储函数的地址以及如何在c / c ++中解析它们?我不清楚这个概念。

3 个答案:

答案 0 :(得分:0)

你有四个指针,所有四个都未初始化。作为一个整体,记忆是否可访问。因此,未初始化的指针指向允许访问的存储器。

在您的情况下,obj指针恰好指向允许您读取的一块内存。因此,读取A指针是有效的,并且可以打印它。然而,这纯粹是随机的 - 在这种情况下,你很幸运。当您再次运行程序或在不同的计算机上运行程序时,无法保证它会再次发生。

同样,DEMO指针恰好指向一块你不允许读取的内存。无论如何都试图这样做会导致分段错误。同样,这纯粹是随机的。

一个好的经验法则是始终初始化指向nullptr的指针。它使您的工作变得更加容易:尝试取消引用nullptr将始终使程序崩溃(无论如何在大多数现代机器上),因此您将更早地警告存在问题。

答案 1 :(得分:-1)

一种可能的解决方案是DEMO-&gt;(* data),因为您将数据声明为指针。我没有尝试过代码,所以我可能错了。 不过,请记住&#34; DEMO-&gt;(* data)&#34;是(* DEMO)。(*数据)的简写。

现在这应该给你一个奇怪的随机值,因为你没有初始化你的指针*数据(如果不是再次出现Seg Fault)。 要做到这一点,要么使用动态分配(使用&#34; malloc / calloc&#34;在C中使用&#34; new&#34;在C ++中,或者只是在结构中静态声明它:

struct demo
{
  int data[NUMBER];
};

其中NUMBER可以是任何正整数。请注意,您不需要*(星号),因为您以数组形式声明了指针(我假设您知道指针和数组几乎是相同的。如果没有,Google会尽快回答。这也将回答您的最终结果问题)。

希望这会有所帮助。祝好运! :)

答案 2 :(得分:-2)

如果你真的想测试差异,你必须对class&amp;结构:

int main()
{
  void *p;

  printf("%u\n", ((struct demo *)p)->A);
  printf("%u\n", ((ABC *)p)->data);

  return 0;
}

现在两个printfs都试图访问相同的内存位置(显然是垃圾,可能不存在),并从那里尝试找到该成员。