是否std::vector::pop_back设置它的对象的指针,nullptr或者它只是删除的对象?
我看到我的向量的大小减小了,所以对象显然被删除了,但我想知道指针是设置为nullptr还是必须手动执行?
编辑:我根据包含指针的向量提出了这个问题。例子:vector<Bitmap*>。
根据这个问题Unable to print the value of nullptr on screen
我无法打印 nullptr 的值,因为它的类型为 nullptr_t,并且 std::cout 没有此类重载。
但是,如果你看看这个:
int* f()
{
return nullptr;
}
int main()
{
std::cout << f();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
00000000
在这个问题Why does std::cout output gone完全消失后 NULL is sent to it他们讨论了一个不同的问题。
我只是想理解为什么std::cout 不能打印 nullptr,但当 nullptr由函数返回时它实际上可以。
当我阅读 Qt 的一些示例代码时,我通常会看到它们初始化了一个指向 的指针nullptr,例如:
QPushButton *startButton = nullptr;
Run Code Online (Sandbox Code Playgroud)
我有一些非常基本的概念nullptr,但自从我开始学习 C++ 以来,我从未真正使用过它。所以我想知道为什么他们会初始化一个指向nullptr而不是这样做的指针:QPushButton *startButton;,这样做有什么好处,我什么时候需要初始化指向nullptr?
提前致谢。
我知道NULL总是如此0,但是为什么下面的代码会打印该消息?
#include <iostream>
using namespace std;
int main() {
int* ptr = nullptr;
if (ptr == 0) {
cout << "Does it always work?";
}
return 0;
}
Run Code Online (Sandbox Code Playgroud) int* x = nullptr;
class_example* obj = nullptr;
Run Code Online (Sandbox Code Playgroud)
我明白 nullprt 是什么,但是这些变量 x 和 obj 在哪里?
堆?还是堆栈?
我有这个模板函数:
template<typename T>
void f(const T* t1, const T* t2) {}
Run Code Online (Sandbox Code Playgroud)
然后在main()中:
int i = 1;
f(&i, NULL);
Run Code Online (Sandbox Code Playgroud)
它不编译,说candidate template ignored: could not match 'const T *' against 'int'
如果改成:
int i = 1;
f(&i, nullptr); // same error!
Run Code Online (Sandbox Code Playgroud)
我知道我可以像这样修复它,指定类型信息:
int i = 1;
f<int>(&i, NULL);
Run Code Online (Sandbox Code Playgroud)
好的,它被编译了。
但是,c++编译器不是可以为我们进行类型推导吗:这样我们就可以在不指定所有类型信息的情况下调用模板函数?
似乎NULL/nullptr 这是模板的一个不寻常的情况。
我的问题:有没有办法f<int>在每个地方都f可以不使用NULL/ nullptr?
谢谢。
以下用于空指针检查的有缺陷的代码可以使用某些编译器进行编译,但不能使用其他编译器进行编译(请参阅godbolt):
\nbool f()\n{\n char c;\n return &c > nullptr;\n}\nRun Code Online (Sandbox Code Playgroud)\n攻击性的部分是指针 和 之间的关系比较nullptr。
比较编译为
\n但是没有版本的 clang (我检查到 4.0)可以编译它。
\n较新的 gcc 产生的错误 (“有序比较指针与整数零 (\'char*\' 和 \'std::nullptr_t\')” 1与 clang 中的错误有点不同 (“二进制表达式的无效操作数 ( \'char *\' 和 \'std::nullptr_t\')")。
\nC++20 ISO 标准在 7.6.9/3ff 中规定了应用于指针的关系运算符:
\n\n如果两个操作数都是指针,则执行指针转换 (7.3.12) [...] 以将它们\n转换为复合指针类型 (7.2.2)。转换后,操作数应具有相同的类型。
\n比较不同对象指针的结果是根据符合以下规则的偏序来定义的:
\n …
\n(4.1) \xe2\x80\x94 如果两个指针指向同一数组的不同元素,或其子对象,指向下标较高的元素的指针需要比较较大。
\n(4.2) \xe2\x80\x94 如果两个指针指向同一对象的不同非静态数据成员,或者指向此类成员的子对象,则递归地要求指向后来声明的成员的指针比较更大,前提是两个成员具有相同的访问控制(11.9),两个成员都不是零大小的子对象,并且它们的类不是联合。
\n(4.3) \xe2\x80\x94 否则,不需要比较两个指针是否大于另一个。
我有Node课。成员是int id, 和指向下一个节点的指针:Node* next。我按如下方式实现了构造函数和析构函数:
#include <iostream>
class Node
{
public:
int id;
Node *next;
Node() : id(0), next(nullptr) {}
explicit Node(int id) : id(id), next(nullptr) {}
~Node() {
std::cout << (*this) << " destructed \n";
delete next;
next = nullptr;
}
friend std::ostream &operator<<(std::ostream &os, const Node &node) {
os << "Node(" << node.id << ")";
return os;
}
};
int main()
{
Node *node0;
Node *node1;
node0 = new Node(0);
node1 = new …Run Code Online (Sandbox Code Playgroud) 我问的是,即使已经为其分配了nullptr,也应删除指针.
例如,在以下情况中:
std::string* foo = new std::string ("foo");
foo = nullptr;
Run Code Online (Sandbox Code Playgroud)
在nullptr释放之前占用内存还是我们面临内存泄漏?
考虑以下函数,如果节点没有子节点,则从二叉搜索树中删除节点:
void erase_no_children(node* todel)
{
//...
if (todel->parent->left == todel) //if todel is left child
todel->parent->left = nullptr;
if (todel->parent->right == todel) //if todel is right child
todel->parent->right = nullptr;
delete todel;
}
Run Code Online (Sandbox Code Playgroud)
因为todel->parent->left == todel这意味着,通过设置todel->parent->left到nullptr,我只是以及设置todel到nullptr.编译器根本没有抱怨.
问题:这样做安全吗?它泄漏了吗?还是未定义的行为?