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

时间:2016-06-19 20:22:22

标签: c++ arrays pointers memory c-strings

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

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;

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

4 个答案:

答案 0 :(得分:1)

运行:

#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 *)&amp; item [i]

是正确的做法。

另请注意,zmbq关于使用调试器查找的评论也是有意义的。

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

答案 1 :(得分:1)

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

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

当您打印((&item) + i)时,您正在进行额外的间接级别(&item是一个指向指针的指针),因此您打印item的地址 - 指针,不是item指向的地址。

注意:: 从C ++ 11开始,您可以使用std::addressof函数代替运算符&,以提高可读性并避免在{{1}时出现潜在问题}为运算符T提供了重载:

&

答案 2 :(得分:0)

可能的方法是将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;

答案 3 :(得分:0)

您获得不同内存地址的原因是您的代码错误。

void printAddresses(type *item, int n)

itemprintAddresses模板函数的指针参数。所以,在下面的表达式中:

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

因此:

&item

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

这就是原因:

 (&item)+i

错了,完全没有意义。模板函数的参数地址在这里并不是非常有用。

 (void*) &item[i]

答案是否正确。