空指针和对象指针

Null Pointers & Object Pointers

本文关键字:指针 对象 空指针      更新时间:2023-10-16

我得到了指示,说明指针变量可以包含指向有效对象、已删除对象、null或随机值的指针。设置四个指针变量a,b,c和d来显示这些可能性。我不确定的是指针对象。有人能解释一下我需要做什么来展示这些指针吗?或者我做得对不对

#include <iostream>
#include <string>
#include <time.h>
using namespace std;
class Pointer
 {
 public:
 Pointer()
{
    int num = 2;
}
Pointer(int num)
{
    this->numb = num;
}
void set(int num)
{
    numb = num;
}
int Get()
{
    return numb;
}
 private:
int numb;

};
int main ()
{
Pointer point;
Pointer* a;
a = &point;
Pointer*b = new Pointer(10);
delete b;
int* c = NULL;
srand(unsigned(time(0)));
int randNum = rand()%100;
int *d;
d = &randNum;
cout <<"Pointer a: " << a << endl;
cout <<"Pointer b: " << b << endl;
cout <<"Pointer c: " << c << endl;
cout <<"Pointer d: " << *d << endl;
//(*a) = (*b);
return 0;

}

不是一个完整的答案,因为这是家庭作业,但这里有一个提示:一旦你生成随机位(c++ STL这样做的方法是<random><chrono>),你可以将它们存储在uintptr_t中,一个与指针大小相同的无符号整数,并将这些位转换为reinterpret_cast<void*>(random_bits)的指针。结果是未定义的行为。试图解引用指针可能会使崩溃,或者看起来工作并破坏其他内存位置,或者它可能在程序的不同运行中做不同的事情,但是您对它所做的任何事情都不能保证可以预测地工作。这是非常糟糕的。

如果"random"真的意味着任意的,对于这个赋值,您可以在堆栈外声明一个指针(也就是说,在函数内而不是static),而不初始化它。如果你不确定,问你的教练。

这是一个非常常见的不可重现bug的来源,我建议您现在养成习惯,在声明指针变量时总是初始化它们。通常,这允许您声明它们为int * const,这是一个很好的实践,但是即使您需要等待为它们分配一个实际值,如果您将指针初始化为NULLnullptr,您总是会立即在调试器中看到该值未初始化,并且如果您试图使用未初始化的值,您总是会使程序崩溃。

我想首先指出NULL这个词或nullptr是什么意思,这是你应该在c++ 11中使用的。空指针只是将指针分配给内存中不可访问的地址或位置。这允许更安全的代码,因为剩下的"悬空指针"可能是不好的。

定义类的头文件和另一个cpp文件

Class Something{
     // Class implementation here
};

现在让我们转到main.cpp文件

#include "The header you made.hpp" // (.h or .hpp)    
int main(int argc, char *argv[]){
     Something objOne;
     Something *objPointer = &objOne;
        // Do stuff with objPointer
             // Like use your member functions
     Something *objPointerTwo = &objOne;
             // Now objPointerTwo points to the same object
     // Lets try some runtime allocation of memory
            Something *objHeap = new Something();
                     // Do something with the pointer
                   // Watch this
           delete objHeap;
           objHeap = nulltpr;
     // Now what happens when you try to access methods again with objHeap 
            // Your program will display a segmentation fault error
            // Which means you are trying to mess with memory
            // that the compiler does not want you too

  }

好的,那么这个内存是什么?简单地说,你有堆和堆栈。当程序被编译时,你放入程序中的所有东西都会被放入堆栈中。因此,当程序运行时,代码跟随main并跟踪堆栈,有点像一堆盒子。你可能需要搜索所有的顶部才能找到底部。现在,如果一个人不知道,比如说,那一年将会有多少学生来上课。程序已经在运行了如何腾出更多的空间?这就是堆的用武之地。new关键字允许您在运行时分配内存,如果您愿意,您可以"指向"堆"上的内存。虽然这一切都很好很酷,但它可能有潜在的危险,这就是为什么人们认为c++和C是危险的语言。当你用完堆上的内存时,你必须"删除"它,这样当指针移动时,内存就不会丢失并导致问题。它有点像一个鬼鬼祟祟的忍者,到处制造麻烦。

考虑指针对对象的好处的一个好方法是,如果你创建一个deck类,用户想要多少张牌,直到运行时我们才知道,所以让他们输入这个数字,然后我们可以在堆上分配它!看下面的

int main(void){
 int count;
 Deck *deck = nullptr;
 std::cout << "Enter amount of cards please:";
 std::cin >> count;
 deck = new Deck(count); // RUNTIME ALLOCATION ON HEAP!!!!
      // This is so cool right, you can have a deck of any size
  // Do stuff with deck

  // Now that we are done with the deck don't forget to delete it 
  // We do not need all those cards on the heap anymore so....
         delete deck; // Ahhh almost done
         deck = nullptr; // Just in case since dangling pointers are weird
}

这里要理解的关键是,什么是指针,它指向什么,以及它们如何与内存一起工作!