【问题标题】:C++ Pointer increment queryC++ 指针增量查询
【发布时间】:2015-08-03 09:32:09
【问题描述】:

我有一个函数的工作代码,该函数接受一个字符和一个数字,并通过复制该字符的次数来形成一个字符串。这是一个完美的作品。

char * buildstr(char c, int n)
{ 
   char * pc = new char[n+1];
   for (int i = 0; i < n; ++i)
   {
      *(pc+i) = c;
   }

   *(pc+n) = '\0';
   return pc;
}

但是,如果我使用另一种逻辑直接递增指针本身,那么当我使用 delete [] 释放主函数中的内存时会出现错误。

我的问题可能是什么?

谢谢,

char * buildstr(char c, int n)
{ 
   char * pc = new char[n+1];
   for (int i = 0; i < n; ++i)
   {
      *pc = c;
      pc++;

   }
   *(pc) = '\0';
   return pc;
}

【问题讨论】:

  • 您正在返回递增的指针,而不是从分配中返回的指针。此外,您应该使用等效且更易读的pc[i],而不是像*(pc+i) 这样的表达式。
  • 这不应该被标记为C,它显然是C++。
  • 请注意,没有必要在 C++ 中编写这样的函数(可能出于学习目的除外),因为 std::string has a constructor (see (2)) 正是这样做的(另一个重要优点:它为您管理内存) .
  • 函数free 期望作为参数起始地址 已使用函数malloc/calloc/realloc 分配的内存块。运算符delete 期望作为操作数起始地址 已使用运算符new 分配的内存块。您不能只在该内存块中传递任何地址。我正要在评论中问你是否真的无法在代码中看到问题,但后来我意识到你认为内存块是一些“原子单元”的软性。

标签: c++ c function pointers increment


【解决方案1】:

问题是您正在返回递增的指针。 delete[] 必须使用调用new[] 返回的指针值来调用,否则你会得到未定义的行为。这同样适用于对free 的调用以及malloccalloc 等返回的指针。

【讨论】:

  • 有时理解 OP 的误解到底在哪里有点棘手。这其实是一个经典的例子。我正要在评论中询问 OP,他/她是否认真对待无法看到问题,但后来我意识到他/她对内存块的看法是一些“原子单元”的软性。也许你应该在你的回答中澄清这个问题,因为我认为这就是 OP 的困惑真正源于的地方(见我对这个问题的评论)。
【解决方案2】:

在第二个示例中,您正在递增指针的值。当你尝试删除它时,它指向数组的最后一个位置。

这样,当您在其上调用delete[] 时,它会崩溃,因为它期望pc 指向最初使用new[] 分配的地址。

我鼓励您使用第一种方法,因为您将能够在 pc 的整个生命周期内跟踪基地址。此外,我认为使用数组表示法更容易做到这一点。

考虑使用:

pc[i] = c;

而不是

*(pc+i) = c;

因为它更惯用且易于阅读。如果您只是在练习指针算术,请坚持您描述的第一种方法。

【讨论】:

  • 谢谢。我熟悉数组表示法,第二个函数不是实现那个东西的好方法。但我这样做是出于学习目的,我得到了一个重要的概念,即 delete[] 期望分配给 new 的相同地址。我不知道。感谢大家的帮助。
【解决方案3】:

在第一个函数中,假设您的指针从 0x00100 开始。 当您执行循环时,您会到达下一个地址,例如 4 循环:

0x00100
0x00101
0x00102
0x00103

但最后你返回 0x00100 上的指针,因为你使用了索引 *(pc+i) 其中i 是索引,所以它很好。

现在在第二个函数上,您正在执行相同的操作,即您在没有索引的情况下移动指针本身,因此您将指针返回到最后一个地址

0x00103

这就是为什么你的第二个功能不起作用

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-02
    • 2018-07-28
    • 2017-12-21
    • 1970-01-01
    • 2010-09-23
    • 2017-01-05
    • 2012-06-11
    • 1970-01-01
    相关资源
    最近更新 更多