为什么两个声明的char *变量获得相同的地址?

时间:2014-03-23 08:23:22

标签: c++ string pointers char

TL; DR:为什么我的char *变量具有相同的值,即使我输入了不同的值?

考虑这个非常短的计划:

char *GetCompleteString ()
{
    char *completeString;
    std::cout << "Please enter the complete string.\n";
    std::cin.getline(completeString,100);
    return completeString;
}

char *GetSubstring ()
{
    char* substring;
    std::cout << "Please enter the substring for which to search.\n";
    std::cin.getline(substring,100);
    return substring;
}


//////////////////////////////////////////////////
int main(int argc, const char * argv[])
{
    char *complete, *sub;

    complete = GetCompleteString();
    sub = GetSubstring();
    //diagnostic
    std::cout << "Complete is " << complete << " and sub is " << sub;
    //diagnostic

    return 0;
}

现在,我为第一个字符串输入“foo”,为第二个字符串输入“bar”。但输出告诉我两个变量是相同的。

Xcode调试器显示两个变量具有相同的地址,因此当我为bar分配值时,先前输入的foo(它位于同一地址)采用相同的值。以下是调试器窗格在程序退出之前显示的内容:

argv      const char **   0x00007fff5fbff928
argc      int             1
complete  char *          0x00007fff5fbff928
*complete char            'b'
sub       char *          0x00007fff5fbff928
*sub      char            'b'
&complete char **         0x00007fff5fbff8e8
&sub      char **         0x00007fff5fbff8e0

为什么这两个变量被分配了相同的地址?我在这里错过了什么? (为什么他们保留与argv相同的地址,我认为这只是为了与CLI连接?)

他们甚至保留了相同的地址吗? (我自己将最后两行(&amp;)行添加到调试器中。那些显示不同的地址......)

3 个答案:

答案 0 :(得分:2)

您正在做的是未定义的行为,因为completeStringsubstring都没有指向实际分配的内存。任何事情都可能发生;)

更确切地说:很可能由于你没有为局部变量赋值,它们只是得到堆栈上的第一个值,它可能是随机的,或者是libc的初始化。离开那里。

答案 1 :(得分:0)

您可以使用以下更新代码

char *GetCompleteString ()
{
    char *completeString = (char*)malloc(sizeof(char)*numberofchars);
    std::cout << "Please enter the complete string.\n";
    std::cin.getline(completeString,100);
    return completeString;
}

char *GetSubstring ()
{
    char* substring =  (char*)malloc(sizeof(char)*numberofchars);
    std::cout << "Please enter the substring for which to search.\n";
    std::cin.getline(substring,100);
    return substring;
}


//////////////////////////////////////////////////
int main(int argc, const char * argv[])
{
    char *complete, *sub;

    complete = GetCompleteString();
    sub = GetSubstring();
    //diagnostic
    std::cout << "Complete is " << complete << " and sub is " << sub;
    //diagnostic

    return 0;
}

我在你的函数中添加了内存分配调用。 numberofchars是你在char *中期望的字符数,或者你可以多考虑​​一下使它变得动态

答案 2 :(得分:0)

您的代码存在一些问题。我会在这里列出它们 -

  1. 语句char *completeString;completeString定义为指向字符的指针。您需要的是一个字符数组,用于存储用户输入的字符串。

  2. 变量completeStringsubString分别是函数GetCompleteStringGetSubstring的本地变量。它们在堆栈上分配,并在函数返回时超出范围。如果您尝试在main中访问它们,则会调用未定义的行为。您需要使用new运算符分配空间来在堆上存储字符串。这会在堆上分配内存。完成后,您应该使用delete[]运算符释放此内存。

  3. 根据标准main的签名应为以下之一 - int main();int main(int argc, char *argv[]);

  4. 将这些更改应用于您的代码,它是

    #include <iostream>
    
    #define MAX_LEN 100  
    
    char *GetCompleteString()
    {
        char *completeString = new char[MAX_LEN];
        std::cout << "Please enter the complete string.\n";
        std::cin.getline(completeString, MAX_LEN);
        return completeString;
    }
    
    char *GetSubstring()
    {
        char* substring = new char[MAX_LEN];
        std::cout << "Please enter the substring for which to search.\n";
        std::cin.getline(substring, MAX_LEN);
        return substring;
    }
    
    int main()
    {
        char *complete, *sub;
    
        complete = GetCompleteString();
        sub = GetSubstring();
    
        std::cout << "Complete is " << complete << " and sub is " << sub;
    
        delete[] sub;
        delete[] complete;
    
        return 0;
    }