【问题标题】:address of first string element yields unexpected result第一个字符串元素的地址产生意外结果
【发布时间】:2017-11-24 10:08:04
【问题描述】:

目标是编写一个函数,输出等于字符的字符串的第一个元素的地址,但是我对结果感到困惑。

当首先使用包含所述字符的字符串评估函数时,我得到字符串开头的地址和第一个元素的地址之间有 2 个字节的差异。例如。 0x7ffe559716d00x7ffe559716e0。 地址不应该一样吗?

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

const char* first_char(const char* str, const char ch)
{
    for (int i = 0; str[i] != 0; ++i)
    {
        if (str[i] == ch)
            return (i+str);
    }
    return 0;
}

int main() {
    string str1 = "jasdfgjhk";
    const char ch1 = 'j';
    cout << &str1 << endl;
    //should be the same address as above?
    cout << (void*)first_char(&str1[0], ch1) << endl;
    return 0;
}

【问题讨论】:

  • cout &lt;&lt; &amp;str1 &lt;&lt; endl; 不输出 char 数组中第一个元素的地址,尝试与 cout &lt;&lt; (void*)str1 &lt;&lt; endl; 相同。
  • 我投票决定关闭它是因为一个简单的印刷错误,因为你只是没有考虑std::string 是如何实现的;它不是char[],因此它的地址当然与其缓冲区中第一个char 的地址不同。
  • @gsamaras 哎呀,我没有发现变量是std::string。所以OP实际上需要cout &lt;&lt; (void*)str1.c_str() &lt;&lt; endl;
  • 我刚刚发布了一个答案@user0042 并使用了data()。我怀疑c_str() 也会成功!你认为我应该在我的回答中包括这个吗?

标签: c++ arrays string pointers memory-address


【解决方案1】:

改变这个:

cout << &str1 << endl;

到这里:

cout << (void*)str1.data() << endl;

您将获得与您的函数返回的地址相同的地址。

原因是std::string不仅仅是一个字符数组,它是一个类,它有一个数据成员是一个数组并存储字符串的字符。

通过使用data(),您将获得该数组。当您打印它的地址时,它会为您提供数组的实际地址,以及之前的类的地址

【讨论】:

  • 您还可以定义一个遗留的字符数组,而不用包裹const char* str1 = "jasdfgjhk"; 的对象。现在str1 只是一个指针,你可以用cout &lt;&lt; (void*)str1 &lt;&lt; endl; 打印它。现在调用函数时不需要转换为指针:first_char(str1, ch1)
  • 是的@PascalRosin 那是真的,那也是 C! ;)
  • 是的,但对于纯 C 语言,您需要使用 printf("%p\n", str1); 之类的内容进行打印 :)
【解决方案2】:

请注意

&str

是“字符串”对象的起始地址。字符串对象不是字符串本身。它包含一个(隐藏的)动态指针,指向字符串本身。所以通过上面你得到“一些东西”,比如一个指向字符串指针的指针。

但是有:

&str1[0]

你真的得到了一个指向字符串中第一个字符的指针。

【讨论】:

    猜你喜欢
    • 2013-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多