【问题标题】:How to check if a certain memory address is available for use in c++?如何检查某个内存地址是否可用于 C++?
【发布时间】:2019-07-04 09:27:22
【问题描述】:

我正在使用 C++ 开发我的爱好项目,并且想测试不同类型变量的连续内存分配(例如具有不同类型变量的数组)。如何检查特定的内存地址是否可用?

更多详情:

假设我们有以下代码:我们有一个整数int_var,(这个变量位于哪个内存地址无关紧要),为了在地址后面分配一个不同类型的变量int_var 的地址我需要检查该地址是否可用,然后使用它。我尝试了以下代码:

int int_var = 5;
float* flt_ptr = (float*)(&int_var + (sizeof(int_var) / sizeof(int)));
// check if flt_ptr is successfully allocated
if (flt_ptr) { // successfully allocated
    // use that address
} else { // not successfully allocated
    cout << "ERROR";
}

问题是:当我运行程序时,有时flt_ptr 被成功分配并且正常,有时没有 - 但是当它没有成功分配时,它会抛出一个异常,显示“读取访问冲突......”打印"ERROR"。这是为什么?也许我错过了检查flt_ptr 是否已成功分配的内容?还是做错了什么?如果是这样,在我使用之前如何检查flt_ptr是否分配成功?

谢谢!!

【问题讨论】:

  • 新展示位置怎么样?
  • 为什么你要“在int_var的地址之后的地址中分配一个不同类型的变量”?如果可能,它会给你带来什么?
  • 在任何情况下,它都不是“分配的,没问题的”。它可能似乎起作用,但它是未定义的行为。如果您需要执行此类操作,请分配一块内存并根据需要使用它。但是您确实需要先分配它。正如有人问的那样,为什么这是必要的?
  • 这似乎是一个XY_Problem,看看 Cmets OP 在 Babajan 的回答中给出的答案:据我所知,他实际上是在寻找一种数据结构来将不同类型存储在连续内存中。
  • 需要澄清的是:您为什么要这样做?

标签: c++ pointers memory-management


【解决方案1】:

您假设的这种内存模型在 DOS 中是有效的,在实模式下,内存是连续的字节流。

现在我们有分页(在 x86 或 x64 中),这是不可能的。因此,您不能对内存“近”内存的存在做出任何假设。

你必须正确分配,这意味着使用 C++ shared_ptr/unique_ptr/STL。或者,新/malloc 旧(坏)方式。

如果您希望变量彼此靠近,请立即分配整个内存(例如,通过结构)。

【讨论】:

    【解决方案2】:

    你不能,C++ 内存模型不能那样工作。

    唯一有效的指针是那些由“&”操作符获得的指针,那些从“new/malloc”和静态数组返回的指针。没有检查内存地址是否(仍然)有效或对象是否已被销毁或根本不存在的机制。所以由程序员来管理指针的正确性。

    由于上述原因,您的程序具有未定义的行为。

    if(pointer) 只检查是否pointer==0,仅此而已。请注意,int n=5; int array[n]; 也不是有效的 C++。不确定你是否正在使用它,但如果你使用了,请不要使用它。

    基于 cmets,您需要一个异构容器。在这种情况下,使用联合数组或更好的std::array&lt;std::variant&lt;int,double,char, float...&gt;&gt; array;。或者std::vector,如果您需要动态大小。

    C++ 保证数组([]mallocnew[])是连续的,但它们只包含一种类型。通常,由于对齐问题,您不能将float, double, int, char 连续存储在一起。上面的arraystd::variant 对象方面是连续的,但它的大小至少是最大类型的大小。所以chars不会打包在一起。

    【讨论】:

    • “一般来说,由于对齐问题,您不能将float, double, int, char 连续存储在一起” - 一般而言:但请注意,大多数编译器上仍然有#pragma pack(1)(假设平台可以处理未对齐的内存访问)。
    【解决方案3】:

    这不是你分配内存的方式。您需要使用new 正确执行此操作。

    here

    【讨论】:

    • 不,他们需要一个自动变量或std::unique_ptr
    • "您需要使用 new 正确执行此操作。"不,这不是您在现代 C++ 中分配内存的方式;)。应避免使用原始 new 以支持智能指针或标准容器
    • 我想在int_var 的地址之后为我的变量分配地址,这对于分配它找到的任何可用地址的new 运算符是不可能的。
    【解决方案4】:

    想要测试一个变量的连续内存分配 不同的类型

    您可以使用结构并将所需的变量声明为成员,以便为不同的数据类型连续分配内存。

    例如:

    struct eg_struct
    {
               unsigned char abc;
               unsigned int  xyz;
    }
    

    请注意,如果需要,您可能需要pack 结构。

    这里不需要检查内存是否空闲。

    【讨论】:

    • 对不起,我希望它像一个包含不同类型变量的数组,在一个数组中,元素一个接一个,我想实现一个包含整数、字符串、字符的数组,浮动,...例如:int i; // 0x00002000. char c; // 0x00002004。等
    猜你喜欢
    • 1970-01-01
    • 2020-07-30
    • 1970-01-01
    • 2020-01-28
    • 2022-01-15
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 2012-03-27
    相关资源
    最近更新 更多