C ++将内存地址转换为值?

时间:2014-06-20 02:47:56

标签: c++ pointers memory

在C ++中,使用iostream,可以打印变量的内存地址。例如:

std::cout << &variable << std::endl;
// Example Result: 002AFD84

但是,如果我想将此内存地址存储到变量中该怎么办?比如将内存地址转换为字符串或双精度(或int等)?或者甚至将该字符串或double(或int等)再次转换回内存地址?

我想出于各种原因这样做,一个是:这将允许我将DLL中的数据的内存地址返回给调用DLL及其功能的程序。除此之外,我不必在DLL中跟踪数据本身,因为数据可以通过它的内存地址来引用。

由于约束,我不能在这种特殊情况下使用指针。约束是:我使用的解释型编程语言无法访问指针。因此,指针不能用于引用DLL外部的数据。

作为一个附带问题,内存地址使用什么数字格式?它们似乎总是长度为8个字符,但我无法弄清楚它是什么格式。

3 个答案:

答案 0 :(得分:4)

要将指针转换为字符串表示形式,可以使用字符串流。这些类似于标准I / O流std::cinstd::cout,但是写入或读取字符串而不是执行I / O.

std::ostringstream oss;
oss << &variable;
std::string address = oss.str();

要将指针转换为表示相同地址的整数,请使用reinterpret_cast。类型uintptr_t(如果存在)保证足够大以容纳任何指针值。但我认为通常只需使用unsigned long

unsigned long address = reinterpret_cast<unsigned long>(&variable);

将指针转换为浮点类似乎没用。您必须先转换为整数类型,然后从那里转换为浮点类型。

答案 1 :(得分:3)

您可以像这样使用reinterpret_cast

uintptr_t address = reinterpret_cast<uintptr_t>(&variable);

在64位(或32位)环境中,内存地址的长度分别为64位(32位)。

答案 2 :(得分:3)

如果您绝对需要这样做,我建议您选择转换为哪种类型。任意将指针转换为非指针类型可能会产生问题,并引入难以检测的问题。如果您使用reinterpret_cast执行转换,则尤其如此。一个更常见的问题是各种平台之间的目标类型的大小。当您使用类似reinterpret_cast的内容时,您通常不会收到有关转换过程中精度损失的警告。

对于需要将指针转换为整数类型的情况,我建议在函数模板中包装这些转换。这将允许您在执行转换时具有一定的灵活性,并且可以执行编译时大小检查以确保目标类型足够大以容纳指针。

下面的代码可能会有所帮助。

template<class DestType, class SourceType>
DestType bubblicious_value_cast(const SourceType& src)
{
    static_assert(sizeof(DestType) >= sizeof(SourceType), "Destination size is too small");
    return reinterpret_cast<DestType>(src);
}

int main()
{
    void* ptr = nullptr;
    int val = bubblicious_value_cast<int>(ptr);
}