【问题标题】:Getting the size of the object void* is pointing to获取对象 void* 的大小指向
【发布时间】:2012-07-20 19:54:15
【问题描述】:
#define BOOST_TEST_MODULE MemoryLeakTest
#include <boost/test/unit_test.hpp>

#include <iostream>
using namespace std;

BOOST_AUTO_TEST_CASE( MemoryLeakTest)
{
    double* n1 = new double(100);
    void* v1 = n1;
    cout << sizeof(v1) << endl;
    delete v1;
}

此代码可以完美运行,不会出现任何错误泄漏。但是我希望能够获得 void* 所保留的对象的大小。我想有一种方法,因为 delete 语句知道对象 v1 指向的大小,以便它可以删除它所以它必须存放在某个地方。

【问题讨论】:

  • 简短回答:你不能。您需要自己跟踪尺寸。
  • 它存储在“某处”——对你来说完全不透明。故意这样。想知道大小,需要自己去追踪。
  • delete 应用于void * 指针在C++ 中一直是非法的。您的代码甚至不应该编译。 (虽然令我惊讶的是,Comeau Online 编译器在 void * 上接受 delete。)
  • @AndreyT 在这里可能有正确的答案;我确实收到了来自clang 的警告。我根本不是 C++ 专家,所以无法直接确认或反驳。
  • @Caesar - 根据语言,这段代码并不能真正工作,只是 似乎工作 是未定义行为的一种可能结果。

标签: c++ sizeof void-pointers


【解决方案1】:

在 C++ 中将 delete 应用于 void * 指针是非法的。

如果您的编译器支持此作为非标准扩展,那么delete 很可能假定该指针指向的未知对象具有平凡的析构函数。在这种情况下,delete 除了立即将控制权交给原始内存释放函数::operator delete(可能只是调用free)之外,不需要做任何事情。 (当然,最后一点取决于实现)。

所以,您的问题基本上归结为“如何确定malloc-ed 内存块的大小”。没有标准功能可以做到这一点。当你分配它时,要么自己记住大小。或者使用非标准实现特定的库功能,如果您的平台提供了任何此类功能。

在某些实现中,这可以通过msize 函数来完成。但同样,为了有意义地做到这一点,您必须首先研究您的实现。您需要弄清楚new 是如何分配内存的和/或delete v1 究竟做了什么,因为它不是标准的C++。

【讨论】:

    【解决方案2】:

    void * 的大小将继续为 sizeof 一个指针。如果您想找出void * 指向的对象的实际大小,您应该知道实际对象并将指针类型转换为正确的类型。不,delete 不会知道对象指针的大小并且会导致泄漏。即使对于delete,正确的做法是确保将指针类型转换为正确的类型。

    【讨论】:

    • 我刚刚运行了程序,没有任何泄漏。正在运行 1 个测试用例... 4 *** 未检测到错误 按任意键继续。 . .
    • 不确定这种情况下的测试用例是什么。您是否正在运行测试套件以通过 valgrind 等检测内存泄漏?
    • @Gangadhar 使用 BOOST_AUTO_TEST_CASE 如果发现泄漏会通知我。
    • @CarlNorum,我不知道。正如 SO stackoverflow.com/a/941953/334642 的其他地方所提到的,删除 void* 不会调用析构函数,并且可能导致泄漏。这就是我所说的泄漏。
    • @Gangadhar,如果你正在删除一个对象,那是真的,但在这种情况下,OP 分配了一个double,它没有没有析构函数。
    【解决方案3】:

    在进行从double *void * 的转换时,您正在丢弃信息供编译器处理。

    因此编译器不知道要调用什么析构函数或对象的大小。

    【讨论】:

      猜你喜欢
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-22
      • 1970-01-01
      • 2013-10-24
      • 2011-10-09
      • 1970-01-01
      相关资源
      最近更新 更多