【问题标题】:C++ strings and pointersC++ 字符串和指针
【发布时间】:2012-03-22 05:25:49
【问题描述】:

我正在学习 C++,目前我正在使用字符串和指针。

我正在关注一本练习册,针对其中一个问题,我创建了以下内容:

#include <iostream>
#include <string>

using namespace std;

int main(void){
    string * firstName=nullptr;
    string * lastName=nullptr;
    string * displayName=nullptr;

    cout << "Enter your first name: " << endl;
    getline(cin,*firstName);

    cout << "Enter your last name: " << endl;
    getline(cin,*lastName);

    displayName=new string;
    *displayName= *lastName + ", " + *firstName;

    cout << "Here's the information in a single string: " << displayName;
    cin.get();
    return 0;
}

为了使用更多的指针,我尝试将它与字符串混合在一起,并因此使解决方案更加复杂。当我运行它时,我得到一个“未处理的异常:访问冲突读取位置 xxxxxxxxx”。

是否有人可以通过仍然使用指针和字符串而不是 char 数组来提出解决方案(我已经知道该怎么做)?

【问题讨论】:

  • 您没有分配字符串,然后将空指针传递给getline() 函数...只需更改所有string *x = nullptr;' to string x;` 或像您一样分配字符串在将它们传递给getline()之前使用displayName
  • 如果您刚刚开始“学习 C++”,那么您不应该靠近原始指针。它们是 C++ 中一个困难的、高级的、小众的部分,大多数“正常”的编程活动都不需要它。
  • 当我对指针感到困惑时,这个video snippet 总是非常鼓舞人心;-)
  • 如果这本书真的建议你使用指向 std::strings 的原始指针作为简单的局部变量,那就扔掉吧。
  • @KerrekSB:“你不应该靠近原始指针”我建议相反。从指针开始,使用 C 风格编程,远离字符串和 STL 等高级概念。几个月后,切换到 STL。 “它们是困难的、高级的”它们是 C++ 的基础部分(“基本素养”级别),你必须学习它们。如果不了解它们,您将无法实现自己的容器,也不会真正了解 STL 的工作原理。不会实现链表的人不能叫程序员,你懂的……

标签: c++ string pointers


【解决方案1】:

这是因为您在使用对象之前没有分配对象:

string * firstName = new string();
//...
delete firstName;

值得补充的是,在这种情况下使用指针毫无意义:标准 C++ 库中的字符串对象从堆中为字符串分配数据;无论如何,字符串通常不过是一对指针。

【讨论】:

    【解决方案2】:

    我认为,您根本不想使用pointers。您可以在没有指针的情况下使用strings

    #include <iostream>
    #include <string>
    
    using namespace std;
    
    int main(void){
      string firstName;
      string lastName;
      string displayName;
    
      cout << "Enter your first name: " << endl;
      getline(cin,firstName);
    
      cout << "Enter your last name: " << endl;
      getline(cin,lastName);
    
      displayName= lastName + ", " + firstName;
    
      cout << "Here's the information in a single string: " << displayName;
      cin.get();
      return 0;
    }
    

    否则,如果需要指针,则必须为变量分配内存:

      cout << "Enter your first name: " << endl;
      firstName = new string();
      getline(cin,*firstName);
    

    ...并使用取消引用运算符 (*) 打印结果:

    cout << "Here's the information in a single string: " << *displayName;
    

    【讨论】:

      【解决方案3】:

      看起来像这样:

      int main()
      {
          std::string* s = new std::string;
          std::getline(std::cin, *s);
          std::cout << *s;
          delete s;
      }
      

      但真的没有理由这样做,只是在堆栈上定义一个普通的字符串变量。

      【讨论】:

        【解决方案4】:

        您收到错误是因为您使用字符串作为指针并且没有初始化它们。这样做的正确方法是:

        #include <iostream>
        #include <string>
        
        using namespace std;
        
        int main(void){
            string firstName;
            string lastName;
            string displayName;
        
            cout << "Enter your first name: " << endl;
            cin >> firstName;
        
            cout << "Enter your last name: " << endl;
            cin >> lastName;
        
            displayName = firstname + ' ' + lastName;
        
        
            cout << "Here's the information in a single string: " << displayName << endl;
            return 0;
        }
        

        您实际上可以使用指向字符串的指针,但它们旨在用作本地对象并作为引用(或 const 引用,如果您愿意)传递。

        【讨论】:

          【解决方案5】:

          访问冲突是因为您取消引用空指针。

          这里设置了空指针

          string * firstName=nullptr;
          

          然后在这里取消引用

          getline(cin,*firstName)
          

          您需要将名字“指向”某些东西(在这种情况下为字符串)。 这是一个没有例外的修改版本。

          int main(void){
              string * firstName= new string();
              string * lastName=new string();
              string * displayName=new string();
          
              cout << "Enter your first name: " << endl;
              getline(cin,*firstName);
          
              cout << "Enter your last name: " << endl;
              getline(cin,*lastName);
          
              //displayName=new string;
              *displayName= *lastName + ", " + *firstName;
          
              cout << "Here's the information in a single string: " << displayName->c_str();
              cin.get();
              return 0;
          }
          

          【讨论】:

          • 嗨,这仍然给了我一个未处理的异常。我正在关闭这种方法,并将坚持简单的路线。谢谢
          • 刚刚发现是我在修复程序后导致了错误。非常感谢您的帮助。
          【解决方案6】:

          阅读10 commandments of c programming。有些对于今天的开发者来说或多或少已经过时了,但有些仍然很重要,比如第二个:

          你不能跟随 NULL 指针,因为混乱和疯狂在等待你。

          这实际上就是你在这里所做的。你的指针无处可去(参见std::nullptr 的分配)。

          要纠正这个问题,您必须将正确类/结构的新对象分配给指针。另外,不要忘记稍后将其删除:

          std::string *myString = new std::string(); // create an object and assign it's address to the pointer
          
          // do something with it... (this part has been right)
          
          delete myString; // free the memory used by the object
          

          【讨论】:

            【解决方案7】:

            由于您使用的是nullptr,我想一个成熟的 C++11 解决方案同样适用:

            #include <iostream>
            #include <memory>
            #include <string>
            
            using namespace std;
            
            int main(void){
                unique_ptr<string> firstName(new string());
                unique_ptr<string> lastName(new string());
                unique_ptr<string> displayName(new string());
            
                cout << "Enter your first name: " << endl;
                getline(cin,*firstName);
            
                cout << "Enter your last name: " << endl;
                getline(cin,*lastName);
            
                *displayName= *lastName + ", " + *firstName;
            
                cout << "Here's the information in a single string: " << *displayName;
            }
            

            当然,使用nullptr 不是你想要的:你需要分配你想要使用的资源。

            请注意,在这些简单的情况下使用指针是在自取其辱,无论是语法还是错误。

            编辑我更正了代码(一个忘记的括号和main最后一行的*),它成功编译并在GCC 4.7上运行。

            【讨论】:

            • 谢谢。我仍然从 xstring 文件中得到未处理的异常错误。你认为视觉工作室有问题吗?我很感激我不应该这样做,我会放弃它并坚持使用字符串的基础知识。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-04-12
            相关资源
            最近更新 更多