【问题标题】:Is setting pointer to null an allocated memory?将指针设置为 null 是分配的内存吗?
【发布时间】:2013-09-04 06:59:17
【问题描述】:

我正在阅读一个将指针初始化为 null 的代码,最初我认为该代码没有将新内存分配给用于存储二维值数组的指针(它确实如此),这让我想知道,是一个初始化为空指针分配的内存?

class Int8_tSet : public GridSet
{
public:
  int8_t** set;
//
//
  Int8_tSet():set(0) {}
  Int8_tSet( const Int8_tSet& x ):set(0) {copy(x);}
  virtual ~Int8_tSet() { Free2DArray(set);}
//
// --- opeartor
  int8_t  operator() ( IntVector2D x ) const {return set[x.i][x.j];}
  int8_t& operator() ( IntVector2D x ) {return set[x.i][x.j];}
// --- function
  void Set();
  void Set(int8_t val);
  void Set( IntVector2D x ){ NS_GRIDDATA::Set(x,*this,(int8_t)-1); }
  void Set( IntVector2D x,int8_t val){ NS_GRIDDATA::Set(x,*this,val); }
  void Switch();
// --- output & input
  void Output(std::ostream& out ) const;
  void Input (std::istream& in  );
// --- copy & substitute
public:
  void copy( const Int8_tSet& x ) {NS_GRIDDATA::Copy(*this,x,(int8_t) -1);}
  const Int8_tSet& operator = ( const Int8_tSet& x );

  void Extract(IntVector2D &ll, IntVector2D &ur,Int8_tSet &subgrid) const;
};


void Int8_tSet::Set()
{
  if(!set) {std::cerr<<" Memory not allocated. Call Set(x) first \n"; exit(1); }
  std::fill(set[0],set[0]+size.i*size.j,-1);
}

我实现了它在void Set中分配内存。

【问题讨论】:

  • 你的问题很不清楚。发布一些代码并尝试指定您实际询问的内容。但是空指针不指向任何地方,所以它也不指向任何动态分配的内存。
  • @Angew 可悲的是,空指针指向某处,以寻址 0 :-) Linux 中存在一个基于 mmap(ping) 页面 0 上的某些内容并等待取消引用空值的漏洞。
  • @xanatos 好的,从实现的角度来看,它指向某个地方,它取决于硬件架构在哪里(它在 x86 上是 0,但这绝不是给定的)。但从语言的角度来看,它并没有指向任何地方。
  • 如果您的问题是“它是动态分配的内存”,那么答案是否定的,除非指针本身是动态分配的。指针只是一个保存值的内置类型,就像intboolbool 是否设置为 false 是“分配的内存”?是和不是,取决于。
  • @Angew 对不起,我已经添加了我正在阅读的代码。

标签: c++ pointers memory null allocation


【解决方案1】:

是一个初始化为空指针的指针,一个分配的内存

我猜这意味着:

type* ptr = NULL;

在这种情况下,内存是为指针本身分配的(关于变量ptr)-即sizeof(type*)
但是它不指向分配的内存,所以@ 987654324@ 是不需要必要的(但仍然安全)。

【讨论】:

    【解决方案2】:

    NULL 是“已知无效”值。它是指针的有效值,但取消引用具有 null 值的指针通常是不安全的(我使用的旧 HP 编译器允许取消引用 null 并且它总是返回“0”)。您可以使用它来检查指针是否有效。

    if (ptr == 0) // in C++ use 0 (or better still nullptr) rather than NULL, 
    {
       ptr = malloc(...);
    }
    doSomethingWithPtr(ptr);
    

    【讨论】:

      【解决方案3】:

      当然不是。除非您使用 new、malloc、calloc a.o. 手动分配内存,否则它不会自行在堆上分配内存。初始化它属于同一类别。 即使您已将其删除/释放内存,指针仍可能指向某些内容。

      {
          char *dp = NULL;
          /* ... */
          {
              char c;
              dp = &c;
          } /* c falls out of scope */
          /* dp is now a dangling pointer */
      }
      

      这是一个来自维基百科的悬空指针示例。

      【讨论】:

        【解决方案4】:

        NULL 用于指定指针何时指向无效地址,即指针指向“任何东西”时,因为未使用。
        使用NULL 初始化指针的习惯是确保指针处于未初始化状态指针指向的内存尚未释放状态。
        最后一个原因是因为在删除它指向的内存后将指针设置为NULL 是一个很好的习惯:例如在C++ 中,operator delete 首先检查指针是否为NULL 以不做任何事情删除。

        在将指针用作参数的情况下,NULL 也用作标记(例如,NULL 表示无效输入)。

        【讨论】:

          【解决方案5】:

          为了,

                is a pointer initialized to a null pointer an allocated memory?
          

          NULL 指针是指向变量指向的内存位置中的“0”的指针。 说,
          int * var=NULL;

          0x104 |----------| ---| | 0 | | 0x100 |---------------------| |用户记忆空间 | . | | | . | ---| | | |----------------------| ---| | | | |----------------------| |操作系统内存区 0x0 |---------------------| ---|

          比如说,'var' 作为一个变量被存储在 32 位机器的内存地址 0x100 到 0x104 中。如果将 0 存储在 'var' 的值位置并取消引用为 *var,这会导致访问属于 OS 内存区域的 0x0 位置。它违反了段,除某些操作系统调用外,进程在所有情况下都应该只访问用户空间。

          因此,NULL 初始化意味着变量中存储的地址无效。切勿访问用户存储区以外的存储区。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-07-30
            • 1970-01-01
            • 2010-12-25
            • 2015-05-01
            • 2021-04-13
            • 1970-01-01
            • 2021-06-22
            • 2015-04-21
            相关资源
            最近更新 更多