在下面的程序中,指针变量可以通过非初始化的类对象访问,但不能通过非初始化的结构指针访问(导致分段错误)??
#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 ++中解析它们?我不清楚这个概念。
答案 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都试图访问相同的内存位置(显然是垃圾,可能不存在),并从那里尝试找到该成员。