空指针和对象指针
Null Pointers & Object Pointers
我得到了指示,说明指针变量可以包含指向有效对象、已删除对象、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
,这是一个很好的实践,但是即使您需要等待为它们分配一个实际值,如果您将指针初始化为NULL
或nullptr
,您总是会立即在调试器中看到该值未初始化,并且如果您试图使用未初始化的值,您总是会使程序崩溃。
我想首先指出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
}
这里要理解的关键是,什么是指针,它指向什么,以及它们如何与内存一起工作!
- 为什么指针对象没有调用默认构造函数
- 如何访问双指针对象中的方法
- 如何使用智能指针对象执行成员函数指针
- 调用带有指针对象错误的指针变量
- 如何从模板类重载创建的指针对象上的运算符?
- C++指针对象的运算符重载
- 如何初始化数组指针对象
- 如何打印出唯一指针对象向量中的值(基于范围的循环)?C++
- C++指针对象差异
- 涉及继承,指针对象的交易以及何时进行的问题
- 表达式必须在C 中具有指针对象类型
- 下标需要数组或指针类型表达式必须具有指针对象类型
- 字符指针对象和相应的字符数组元素比较
- 如何在 c++ 中克隆为弱指针对象
- 指针对象使用CPP中的指针表达式进行比较
- Visual Studio中智能指针对象的自定义视图
- 使用指针 /对象 /模板参数正确构成
- 如果我确定只有一个线程一次处理指针/对象,则C/C 仍应使用同步
- 如何将值分配给指针对象 c++
- 更改智能指针对象,然后访问它