C++ 指针的默认构造函数是什么?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/936999/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What is the default constructor for C++ pointer?
提问by Milan Babu?kov
I have code like this:
我有这样的代码:
class MapIndex
{
private:
typedef std::map<std::string, MapIndex*> Container;
Container mapM;
public:
void add(std::list<std::string>& values)
{
if (values.empty()) // sanity check
return;
std::string s(*(values.begin()));
values.erase(values.begin());
if (values.empty())
return;
MapIndex *&mi = mapM[s]; // <- question about this line
if (!mi)
mi = new MapIndex();
mi->add(values);
}
}
The main concern I have is whether the mapM[s] expression would return reference to NULL pointer if new item is added to the map?
我主要关心的是,如果将新项目添加到地图中,mapM[s] 表达式是否会返回对 NULL 指针的引用?
The SGI docssay this: data_type& operator[](const key_type& k) Returns a reference to the object that is associated with a particular key. If the map does not already contain such an object, operator[] inserts the default object data_type().
的SGI文档这样说:DATA_TYPE&运算符[](常量为key_type&K)返回到与特定键相关联的对象的引用。如果地图尚未包含此类对象,operator[] 将插入默认对象 data_type()。
So, my question is whether the insertion of default object data_type()will create a NULL pointer, or it could create an invalid pointer pointing somewhere in the memory?
所以,我的问题是插入默认对象 data_type()是否会创建一个 NULL 指针,或者它可能会创建一个指向内存中某处的无效指针?
采纳答案by Mehrdad Afshari
It'll create a NULL
(0) pointer, which is an invalid pointer anyway :)
它会创建一个NULL
(0) 指针,无论如何它都是一个无效的指针:)
回答by Jamie Cook
Yes it should be a zero (NULL) pointer as stl containers will default initialise objects when they aren't explicitly stored (ie accessing a non-existant key in a map as you are doing or resizing a vector to a larger size).
是的,它应该是一个零 (NULL) 指针,因为当 stl 容器没有显式存储对象时,它们将默认初始化对象(即在您执行操作时访问映射中不存在的键或将向量调整为更大的大小)。
C++ Standard, 8.5 paragraph 5 states:
C++ 标准,8.5 第 5 段指出:
To default-initialize an object of type T means:
- If T is a non-POD class type (clause class), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor)
- If T is an array type, each element is default-initialized
- Otherwise, the storage for the object iszero-initialized.
默认初始化 T 类型的对象意味着:
- 如果 T 是非 POD 类类型(子句类),则调用 T 的默认构造函数(如果 T 没有可访问的默认构造函数,则初始化是格式错误的)
- 如果 T 是数组类型,则每个元素都默认初始化
- 否则,对象的存储是零初始化的。
You should also note that default initialisation is different to simply ommiting the constructor. When you omit the constructor and simply declare a simple type you will get an indeterminate value.
您还应该注意,默认初始化与简单地省略构造函数不同。当您省略构造函数并简单地声明一个简单类型时,您将获得一个不确定的值。
int a; // not default constructed, will have random data
int b = int(); // will be initialised to zero
回答by Milan Babu?kov
UPDATE:I completed my program and that very line I was asking about is causing it to crash sometimes, but at a later stage. The problem is that I'm creating a new object without changing the pointer stored in std::map. What is really needed is either reference or pointer to that pointer.
更新:我完成了我的程序,我问的那一行有时会导致它崩溃,但在稍后阶段。问题是我正在创建一个新对象而不更改存储在 std::map 中的指针。真正需要的是引用或指向该指针的指针。
MapIndex *mi = mapM[s]; // <- question about this line
if (!mi)
mi = new MapIndex();
mi->add(values);
should be changed to:
应改为:
MapIndex* &mi = mapM[s]; // <- question about this line
if (!mi)
mi = new MapIndex();
mi->add(values);
I'm surprised nobody noticed this.
我很惊讶没有人注意到这一点。
回答by Bojan Resnik
The expression data_type()
value-initializes an object. For a class type with a default constructor, it is invoked; if it doesn't exist (or is defaulted), such as pointers, the object is zero-initialized.
表达式data_type()
值初始化一个对象。对于具有默认构造函数的类类型,它会被调用;如果它不存在(或被默认),例如指针,则对象被零初始化。
So yes, you can rely on your map creating a NULL
pointer.
所以是的,您可以依靠地图创建NULL
指针。
回答by vladimir venediktov
Not sure about the crash, but there's definitely a memory leak as this statement:
不确定崩溃,但肯定有内存泄漏,因为这个语句:
if (!mi)
mi = new MapIndex();
always returns true, because pointer mi
is not a reference to to what mapM
is holding for a particular value of s
.
始终返回 true,因为指针mi
不是对mapM
为 的特定值所持有的内容的引用s
。
I would also avoid using regular pointers and use boost::shared_ptr
or some
other pointer that releases memory when destroyed. This allows you to call mapM.clear()
or erase()
, which should call destructors of keys and values stored in the map. Well, if the value is POD such as your pointer then no destructor is called therefor unless manually deleted, while iterating through a whole map will lead to memory leaks.
我也会避免使用常规指针并使用boost::shared_ptr
或其他一些在销毁时释放内存的指针。这允许您调用mapM.clear()
or erase()
,它应该调用存储在映射中的键和值的析构函数。好吧,如果值是 POD,例如您的指针,那么除非手动删除,否则不会为此调用析构函数,而遍历整个映射将导致内存泄漏。