【问题标题】:Why are two declared char* variables getting the same address?为什么两个声明的 char* 变量获得相同的地址?
【发布时间】:2014-04-30 13:54:14
【问题描述】:

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 整数 1 完整字符 * 0x00007fff5fbff928 *完整的字符'b' 子字符 * 0x00007fff5fbff928 *子字符'b' &complete char ** 0x00007fff5fbff8e8 &sub char ** 0x00007fff5fbff8e0

为什么这两个变量被分配了同一个地址?我在这里想念什么? (为什么他们保留与 argv 相同的地址,我认为这只是为了与 CLI 交互?)

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

【问题讨论】:

  • 你永远不会为char *分配内存。地址只是内存中的某个随机位置。
  • 无关的挑剔:从技术上讲,argv 不应该是const
  • 删除了c标签,这是C++,不是C。
  • @calccrypto 和 filmor:我没有看到任何示例(在我面向初学者的书籍和研究中)表明您需要在声明之外进行任何类型的分配。我需要在这里添加什么?
  • @Cornstalks:这是从调试器窗格复制和粘贴的。与苹果公司合作。 :-D

标签: c++ string pointers char


【解决方案1】:

由于completeStringsubstring 均未指向实际分配的内存,因此您正在执行的操作存在未定义的行为。任何事情都有可能发生;)

更准确地说:很可能因为你没有给局部变量赋值,他们只是得到了堆栈上的第一个值,这可能是随机的,或者你的 libc 的初始化留在了那里.

【讨论】:

    【解决方案2】:

    您可以使用以下更新的代码

    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 * 中的字符数,或者您可以多考虑​​一下使其动态化

    【讨论】:

    • 完成字符串后不要忘记使用free()。此外,sizeof(char) 的定义为 1,因此无需乘以 sizeof(char)
    • 另外,numberofchars 在这段代码中既没有声明也没有定义。
    【解决方案3】:

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

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

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

    3. main 的签名按照标准应该是以下之一 - int main();int main(int argc, char *argv[]);

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

    #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;
    }
    

    【讨论】:

    • 谢谢,阿杰——这对于像我这样的菜鸟来说非常棒和简单! :-)
    猜你喜欢
    • 2017-01-04
    • 1970-01-01
    • 2020-03-09
    • 1970-01-01
    • 2023-04-05
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多