地址函数始终返回相同的值

时间:2016-06-20 18:06:49

标签: c++11

我有一个名为'Address'的函数:

template <class Variable> unsigned long Address(Variable *X){
    return (unsigned long &) X;
}

此函数返回给定参数的地址。即使给出了论证 它不是变量,它返回一个值,当我将此值指向另一个指针时,我可以访问该值。

当我正在使用这个函数时,我看到这个函数总是在非变量(如“Hello world!”)参数上返回相同的值。

cout << "Address (?) of 'Hello world!' :" << Address("Hello world!") << "\n";

cout << "Address (?) of 'Hello world' :" << Address("Hello world") << "\n";

提供相同的输出。但是当我尝试

cout << "Address (?) of 'Hello world!' :" << Address("Hello world!") << "\n";
cout << "Address (?) of 'Hello world!' :" << Address("Hello world") << "\n";

在同一个文件中执行此操作,输出不同

这是为什么?

2 个答案:

答案 0 :(得分:4)

字符串文字的地址完全依赖于编译器。在您的情况下,您的两个单独的程序每个编译一个*字符串文字参数并最终给它相同的地址。在单程序示例中,有两个单独的文字,它们有两个不同的地址。

当编译器遇到字符串文字时,它会为二进制输出文件留出空间(有时称为“数据段”)。这是二进制文件中专门用于数据而不是可执行代码的位置。根据编译器的决策,它可以选择文件中的不同位置。但是,因为数据在文件内部,所以每次运行时它的地址总是相同的。

在你的第一个例子中,你有两个不同的二进制文件,每个文件只有一个字符串文字,编译器碰巧做出了关于字符串放置位置的相同决定,因此它们都给出了相同的答案。

在第二个示例中,您有一个二进制文件,其中包含两个不同的字符串文字,因此它们当然具有单独的地址。

*从技术上讲,分别有两个和四个文字;我专注于用作函数参数的文字。

答案 1 :(得分:3)

C ++以实现定义的方式将字符串的内容放入内存中。通常,程序的所有字符串都将背靠背放置在一段内存中,'\0'终止符标记其结尾。实际放置主要取决于编译器,但也取决于是否存在可能放在您要打印的地址之前的其他常量。

这就是为什么来自不同程序的地址的比较毫无意义。编译器可以自由地将字符串文字的表示放在任何位置。

例如,地址可能会因为在程序中添加另一个字符串文字而发生变化。此代码打印的地址

cout << addr("Hello, world!") << endl;

和此代码

cout << "Here is the address: " << addr("Hello, world!") << endl;

是不同的,即使常数相同(demo 1demo 2)。

但是,来自同一程序的不同字符串文字的地址保证不同。此外,如果翻译单元单独编译然后链接到单个程序中,具有相同内容的字符串文字可能有多个地址。

注意:请勿投放到unsigned long,但不保证能够正常使用。 Use uintptr_t instead.