动态内存分配,堆,间接,NULL

时间:2014-03-06 19:10:35

标签: c++ heap indirection

我试图保证动态分配的内存无法指向。

我尝试了以下

template<typename T>
[...something here...]
T *mem = new T[size];

for ( int i=0; i<size; i++ )
{
    (mem+i) = NULL;
}  
[...something else there...]

正如人们可以写的那样

int *pInt = new int;
pInt = NULL;

但这不起作用,因为在上面的示例中mem不是“左值”?

为什么只有在动态分配堆上特定类型的内存时才会出现这种情况?

另外,如果我使用模板函数会发生一件奇怪的事情,因为编写

似乎是合法的
template<typename T>
[...something here...]
T mem = new T[size];

for ( int i=0; i<size; i++ )
{
    *(mem+i) = NULL;

    /* or the equivalent
    mem[i] = NULL;
    */
}  
[...something else there...]

怎样才能将NULL(基本上是int值0)分配给一个基本上可以是任何东西的变量或对象?它可能是int变量,很好,它可以工作。但是,如果我使用std::string调用模板函数,该怎么办?它应该不起作用,对吗?那么为什么写这样的东西似乎是合法的呢?

是否可以自由编程泛型,但也有责任注意,而不是调用错误类型的某些通用函数?

2 个答案:

答案 0 :(得分:1)

  

但它不起作用,因为在上面的例子中“mem”不是“左值”?

的确,您正在尝试重新分配临时指针mem+i;这没有意义。据推测,您希望将数组成员(mem[i]*(mem+i))设置为某个内容;虽然可能不是NULL,除非T应该是指针类型。

在具有单个对象的示例中,您将重新分配指向已分配对象的唯一指针;所以你无法使用或删除该对象。

  

怎样才能将NULL(基本上是int值0)分配给一个基本上可以是任何东西的变量或对象?

因为,在C ++ 11之前,唯一有效的空指针常量(因此NULL宏的唯一有效扩展)是零值整数常量;所以代码扩展为类似

*(mem+i) = 0;

对许多类型都有效。现在,NULL可能(或可能不会)扩展为nullptr,在这种情况下,它只对指针类型有效。

  

但是如果我用std :: string调用模板函数怎么办?它应该不起作用,对吗?

std::string有一个构造函数和赋值运算符,它指向一个C风格的字符串,例如允许

std::string hello = "Hello, world!";

这些也可以采用空指针,给出未定义的行为。

答案 1 :(得分:0)

您的代码是:

for ( int i=0; i<size; i++ )
{
  (mem+i) = NULL;
}

在这种情况下,(mem+i)是临时结果,称为rvalue。 rvalues是临时的,你不能为它们赋值。您只能为左值分配值。 (顺便说一下,我认为这不是你想做的事情:我想你想改变指针显示的内存而不是指针中存储的地址值)

for ( int i=0; i<size; i++ )
{
  mem[i] = NULL;
 *(mem+i) = NULL;
}

在这种情况下,还会计算临时结果(在mem+i两种情况下),但它们用于寻址正确的内存。因此,在这两种情况下,指向的内存都是左值。

如果你使用模板,你必须记住这些是模板;-) 如果模板未在任何地方使用,则永远不会编译模板代码。如果使用它,则取决于您用作模板参数的变量/类的类型。

您可以编写此代码:

template<typename T>
void func( T a)
{
  a.foo = "bar";
  a.my_func( 3.14);
}

此代码看起来是strang,但它将为每个a编译,该foo具有成员变量/对象const char的任何结构或类,可以为其分配operator ()和成员函数或函数指针或具有名称my_func的重载{{1}}的对象。