为什么非初始化类对象指针可以访问指针成员,而结构指针不能访问指针变量

why non intitialized class object pointer can access pointer member and struct pointer can not access pointer variable

本文关键字:指针 访问 成员 结构 变量 不能 初始化 对象 为什么      更新时间:2023-10-16

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

#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 constructorn";
   }
  //display function..
  void displayA()
  {
    printf("display An");
  }

};
int main()
{
  ABC *obj;  //class object pointer..
  struct demo *DEMO;  //structure pointer
  printf("%un",obj->A);  //works properly no segmentation fault
  printf("%un", 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++中解析这些地址?我不清楚这个概念。

您有四个指针,而这四个指针都未初始化。内存,作为一个整体,要么是可访问的,要么是不可访问的。因此,一个未初始化的指针指向允许或不允许访问的内存。

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

类似地,DEMO指针恰好指向一块不允许读取的内存。无论如何,尝试这样做都会导致分段错误。同样,这完全是随机的。

一个好的经验法则是总是初始化指向nullptr的指针。这让你的工作变得容易多了:试图取消引用nullptr总是会使程序崩溃(无论如何,在大多数现代机器上),所以你会更早地被警告存在问题。

一个可能的解决方案是DEMO->(*data),因为您将数据声明为指针。我还没有试过这个代码,所以我可能错了。不过,请记住"DEMO->(*data)"是(*DEMO)的简写。(*数据)。

现在,这应该会给你一个奇怪的随机值,因为你没有初始化指针*数据(如果不是Seg Fault)。要做到这一点,可以使用动态分配(在C中使用"malloc/calloc"或在C++中使用"new",或者简单地在结构中静态声明它:

struct demo
{
  int data[NUMBER];
};

其中NUMBER可以是任何正整数。请注意,您不需要*(星号),因为您以数组形式声明了指针(我想您知道指针和数组几乎是一样的。如果不是,请尽快在谷歌上搜索。这也将回答您的最后一个问题)。

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

如果你真的想测试差异,你必须对两个类使用相同的指针;结构:

int main()
{
  void *p;
  printf("%un", ((struct demo *)p)->A);
  printf("%un", ((ABC *)p)->data);
  return 0;
}

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