C++ strings en pointers

Ik ben C++ aan het leren en momenteel werk ik met strings en pointers.

Ik volg een werkboek en voor een van de vragen heb ik het volgende gemaakt:

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

In een poging om meer pointers te gebruiken, heb ik geprobeerd het te combineren met strings en heb ik de oplossing om deze reden complexer gemaakt. Als ik dit uitvoer, krijg ik de melding “Onverwerkte uitzondering: leeslocatie voor toegangsschending xxxxxxxxx”.

Kan iemand hier een oplossing voor voorstellen door nog steeds pointers en strings te gebruiken in plaats van char-arrays (waarvan ik al heb ontdekt hoe ik dat moet doen)?


Antwoord 1, autoriteit 100%

Dit komt omdat u uw objecten niet heeft toegewezenvoordat u ze gebruikt:

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

Het is de moeite waard om toe te voegen dat het gebruik van pointers in deze situatie, nou ja, zinloos is: tekenreeksobjecten in de standaard C++-bibliotheek wijzen de gegevens voor de tekenreeks toe vanaf de heap; strings zijn sowieso meestal niet veel meer dan een paar wijzers.


Antwoord 2, autoriteit 25%

Ik denk dat je helemaal geen pointerswilt gebruiken. Je kunt werken met stringszonder pointers.

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

Anders, als je pointers nodig hebt, moet je geheugen toewijzen voor variabelen:

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

…en print resultaat met dereferentie-operator (*):

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

Antwoord 3, autoriteit 12%

Het zou er zo uitzien:

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

Maar er is echt geen reden om dit te doen, definieer gewoon een normale stringvariabele op de stapel.


Antwoord 4, autoriteit 12%

Je krijgt fouten omdat je strings als aanwijzers gebruikt en je ze niet initialiseert. Een correcte manier om dit te doen zou zijn:

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

Je mag eigenlijk pointers naar strings gebruiken, maar ze zijn bedoeld om als lokaal object te worden gebruikt en als referenties door te geven (of const-referenties, als je dat wilt).


Antwoord 5, autoriteit 6%

De toegangsfout is omdat u een null-pointer derefeert.

Null-aanwijzer is hier ingesteld

string * firstName=nullptr;

en dan hier verwijderd

getline(cin,*firstName)

Je moet de voornaam ‘point’ hebben naar iets (een string in dit geval).
Hier is een aangepaste versie zonder uitzonderingen.

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

Antwoord 6

Lees de 10 Geboden van C-programmering . Sommige zijn min of meer verouderd voor de Devs van vandaag, maar sommige zijn nog steeds belangrijk, zoals de tweede:

Gij zult de null-aanwijzer niet volgen, voor chaos en waanzin wachten u aan het einde.

Dat is eigenlijk wat je hier doet. Uw Pointers wijzen nergens aan (zie de opdrachten aan std::nullptr).

Om dit te corrigeren, moet u een nieuw doel van de juiste klas / struct toewijzen aan de aanwijzer. Vergeet ook niet om het later te verwijderen:

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

Antwoord 7

Aangezien u nullptrgebruikt, denk ik dat een volledig-geblazen C++ 11-oplossing even fijn is:

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

Natuurlijk met behulp van nullptrwas niet wat u wilde: u moet de middelen die u wilt gebruiken toewijzen.

Houd er rekening mee dat het gebruik van aanwijzers in deze eenvoudige gevallen jezelf in de voet schieten, zowel qua syntaxis als qua bugs.

EDITIk heb de code gecorrigeerd (een vergeten haakje en de *op de laatste regel van main), het compileert en draait op GCC 4.7.

Other episodes