【问题标题】:C++ : deleting different static and dynamic pointer type [closed]C++:删除不同的静态和动态指针类型
【发布时间】:2016-12-15 13:33:27
【问题描述】:

我有一段愚蠢的代码,我需要一些解释。

int main() {
   int *ptr_i = new int[100];
   char *ptr_c = (char *)ptr_i;
   delete [] ptr_c;
   return 0;
}

首先,我预计这段代码会崩溃,但我相信它没有崩溃,因为在这种情况下,分配器将跟踪要取消分配的字节数。我也在这段代码上运行了 valgrind,它没有显示内存泄漏。 我需要澄清以下内容:

  1. 如果在处理 POD 数据类型时,char 的 c'tor 与 int 的 c'tor 有何不同?

  2. 除了编码约定,这段代码还会导致什么其他问题?

【问题讨论】:

  • 如果它看起来像未定义的行为......并且走路像未定义的行为......
  • 在我看来像 UB。如果它们是非 pod 类型,则永远不会调用析构函数。
  • "这段代码还会导致什么其他问题" 随便。这就是未定义行为的本质。使这个问题过于笼统。说真的,目前还不清楚你的实际问题是什么。你知道代码是错误的(“哑巴”),所以你在问什么?为什么它仍然有效?谁知道呢,它是依赖于实现的,你没有给我们足够的信息来推测。为什么答案甚至会有用?你不应该写这样的代码。
  • 它的 C 对应项在语义上应该是有效的:prt_i = malloc(100*sizeof(int)) ... free(ptr_c) 即使分配和取消分配之间的对称性对于未来的代码审查来说是可取的。跨度>

标签: c++


【解决方案1】:

int 没有构造函数,char 也没有构造函数。但是,由于运算符delete(更准确地说是delete [])的使用与运算符newnew [])的使用不匹配,因此行为未定义。

未定义的行为并不意味着会发生崩溃。这并不意味着会发生内存泄漏。

这只是意味着 C++ 标准对发生的事情没有任何限制。

崩溃可能会发生,也可能不会发生。可能会或可能不会发生内存泄漏。编译器可能会也可能不会重新格式化您的硬盘驱动器。您的程序可能会或可能不会打印值42 总共27 次。您可以想象的任何其他事件可能会发生也可能不会发生。

因此,此类代码可能导致的问题可能是......任何事情......甚至什么都没有。最大的问题是你不一定知道。

【讨论】:

  • 由于 delete[] 调用是程序中的最后一件事,因此即使是堆损坏和其他 UB 后果的最坏情况也很难观察到。
  • @Lorenzo - 是的,除非 UB 导致 return 0; 的行为类似于 system("format C:");
猜你喜欢
  • 2017-07-03
  • 2016-02-03
  • 2021-05-19
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 2019-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多