如何打印出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;
函数打印动态数组每个内存位置的地址。这是正确的方法吗?
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;