如何打印出C-String的内存地址?

How to print out memory addresses of C-String?

函数打印动态数组每个内存位置的地址。这是正确的方法吗?

int main()
{
    char str[] = "This is a test";
    printAddresses(str, strlen(str));
}

template <class type>
void printAddresses(type *item, int n)
{
    cout << "Printing Addresses..." << endl;
    for (int i = 0; i < n; i++)
    {
        cout << "Index " << i << ": " << ((&item) + i)  << endl;
    }

}

我也听说我应该使用:

cout << "Index " << i << ": " << (void*) &item[i] << endl;

但这给了我不同的内存地址。我不确定哪个是正确的。

一种可能的方法是使用 C 风格 printf%p。所以包括 <cstdio> 然后尝试例如:

 const char *sp = "abcde" + 2; // some computation giving a string address
 printf("sp=%p ('%s')\n", sp, sp);

或者,转换为 (void*) 并使用通常的

std::cout << "sp at " << (void*)sp << std::endl;

运行 这个:

#include <iostream>
#include <cstring>
using namespace std;

template <class type>
void printAddresses(type *item, int n)
{
    cout << "Printing Addresses..." << endl;
    for (int i = 0; i < n; i++)
    {
        cout << "Index " << i << ": " << ((&item) + i)  << endl;
        cout << "Index2 " << i << ": " << (void*) &item[i] << endl;
    }

}

int main()
{
    char str[] = "This is a test";
    printAddresses(str, strlen(str));
}

在我的机器上打印:

gsamaras@gsamaras-A15:~$ g++ -Wall main.cpp
gsamaras@gsamaras-A15:~$ ./a.out
Printing Addresses...
Index 0: 0x7ffd5c9ead58
Index2 0: 0x7ffd5c9ead90
Index 1: 0x7ffd5c9ead60
Index2 1: 0x7ffd5c9ead91
Index 2: 0x7ffd5c9ead68
Index2 2: 0x7ffd5c9ead92
Index 3: 0x7ffd5c9ead70
Index2 3: 0x7ffd5c9ead93
Index 4: 0x7ffd5c9ead78
Index2 4: 0x7ffd5c9ead94
Index 5: 0x7ffd5c9ead80
Index2 5: 0x7ffd5c9ead95
Index 6: 0x7ffd5c9ead88
Index2 6: 0x7ffd5c9ead96
Index 7: 0x7ffd5c9ead90
Index2 7: 0x7ffd5c9ead97
Index 8: 0x7ffd5c9ead98
Index2 8: 0x7ffd5c9ead98
Index 9: 0x7ffd5c9eada0
Index2 9: 0x7ffd5c9ead99
Index 10: 0x7ffd5c9eada8
Index2 10: 0x7ffd5c9ead9a
Index 11: 0x7ffd5c9eadb0
Index2 11: 0x7ffd5c9ead9b
Index 12: 0x7ffd5c9eadb8
Index2 12: 0x7ffd5c9ead9c
Index 13: 0x7ffd5c9eadc0
Index2 13: 0x7ffd5c9ead9d

现在想想您希望看到的存储字符序列是什么?您希望每个字符都与前一个字符相邻(当然),并且每个字符都占用 1 个存储单元。那应该告诉你:

(void*) &item[i]

是正确的做法。


另请注意 zmbq 的评论,关于使用调试器找出答案也很有意义。


最后,我建议您阅读:Printing array element memory adresses C and C++, why different output?

你得到不同内存地址的原因是你的代码有误。

void printAddresses(type *item, int n)

item 是指向您的 printAddresses 模板函数的指针参数。所以,在下面的表达式中:

    cout << "Index " << i << ": " << ((&item) + i)  << endl;

因此:

&item

成为模板函数的参数地址,而不是数组地址。

这就是为什么:

 (&item)+i

是错误的,毫无意义。模板函数的参数地址在这里不是很有用。

 (void*) &item[i]

是正确答案。

正确的地址是您打印时得到的地址(void*)&item[i]

item 已经是一个指针; &item[i] 也是如此。您有兴趣打印此指针的值,需要在调用 << 之前将其转换为 void*

当你打印 ((&item) + i) 时,你正在做一个额外的间接级别(&item 是一个指向指针的指针),所以你打印 item-the- 的地址指针,而不是 item 指向的地址。

注意:: 从 C++11 开始,您可以使用 std::addressof 函数代替运算符 & 以获得更好的可读性并避免潜在问题当 T 为运算符 &:

提供重载时
cout << "Index " << i << ": " << std::addressof(item[i]) << endl;