#include <iostream> #include <cstring> #include <cctype> using namespace std; struct Train { int number; char *Location[100]; char *departure[10]; }; Train* AddStruct(Train* Obj, const int number); void input(Train* Obj, const int number); void show(const Train* Obj, const int number); int main() { Train *City; int n; int count = 0; cin >> n; for (int i = 0;i < n;i++) { input(City,count); count++; } show(City, count); delete[] City; return 0; } Train* AddStruct(Train* Obj, const int number) { if (number == 0) { Obj = new Train[number + 1]; } else { Train* tempObj = new Train[number + 1]; for (int i = 0; i < number; i++) { tempObj[i] = Obj[i]; } delete[] Obj; Obj = tempObj; } return Obj; } void input(Train* Obj, const int number) { cin >> Obj[number].number; cin >> *Obj[number].Location; cin >> *Obj[number].departure; } void show(const Train* Obj, const int number) { for (int i = 0; i < number; i++) { cout << Obj[i].number << '\t' << Obj[i].Location << '\t' << Obj[i].departure << endl; } } 

I can not understand why the program is breaking. I will be glad to any help. PS I'm still new.

Closed due to the fact that off-topic participants are Vladimir Martyanov , Kromster , D-side , αλεχολυτ , pavel 26 Oct '16 at 18:03 .

It seems that this question does not correspond to the subject of the site. Those who voted to close it indicated the following reason:

  • “Questions asking for help with debugging (“ why does this code not work? ”) Should include the desired behavior, a specific problem or error, and a minimum code for playing it right in the question . Questions without an explicit description of the problem are useless for other visitors. See How to create minimal, self-sufficient and reproducible example . " - Vladimir Martyanov, Kromster, D-side, αλεχολυτ, pavel
If the question can be reformulated according to the rules set out in the certificate , edit it .

  • 2
    What exactly is going to have to guess, right? - Vladimir Martyanov
  • It breaks after I enter cin >> Obj [number] .number; - Kairat Amanzharov

2 answers 2

There are several problems in the program.

First, you did not allocate memory for an array of objects of type Train . The City pointer is not initialized and has an undefined value.

 Train *City; ^^^^^^^^^^^^ 

Therefore, when using this pointer in this function

 void input(Train* Obj, const int number) { cin >> Obj[number].number; cin >> *Obj[number].Location; cin >> *Obj[number].departure; } 

leads to indefinite program behavior.

But even if you selected the array and this pointer was initialized with the address of the first element of the array, the program is nevertheless incorrect, as in these sentences of the above function

  cin >> *Obj[number].Location; cin >> *Obj[number].departure; 

You are also trying to use the non-initialized Obj[number].Location and Obj[number].departure .

Declaring these structure fields as they appear

 struct Train { int number; char *Location[100]; ^^^^^^^^^^^^^^^^^^^^ char *departure[10]; ^^^^^^^^^^^^^^^^^^^^ }; 

don't make sense. You declared arrays from char * pointers instead of declaring arrays of char objects. I think you meant the following ad

 struct Train { int number; char Location[100]; ^^^^^^^^^^^^^^^^^^^^ char departure[10]; ^^^^^^^^^^^^^^^^^^^^ }; 

Since in the AddStruct function you delete an array addressed by the first parameter,

 Train* AddStruct(Train* Obj, const int number) { if (number == 0) { Obj = new Train[number + 1]; } else { Train* tempObj = new Train[number + 1]; for (int i = 0; i < number; i++) { tempObj[i] = Obj[i]; } delete[] Obj; Obj = tempObj; } return Obj; } 

then when calling it, you should remember to assign the return value to the pointer that was passed to the function as an argument. For example,

 City = AddStruct( City, count ); 

This is not quite clear intuitive interface. The user of this function may forget to assign the result of the function to the same pointer that was used as the argument.

The second remark to the function is that you should not separate the two cases in the function when the number parameter is 0 or not 0. If the number parameter is 0, then the first parameter should be nullptr , and therefore it can also be In this case, apply the delete [] operator to this pointer.

Based on the above, I would declare this function as follows.

 int AddStruct( Train * &Obj, int number ) { Train* tempObj = new Train[number + 1]; for ( int i = 0; i < number; i++ ) { tempObj[i] = Obj[i]; } delete [] Obj; Obj = tempObj; return number + 1; } 

EDIT: Taking into account what you said in the comments, the program might look like this.

 #include <iostream> struct Train { unsigned int number; char *location; char *departure; }; const size_t LOCATION_LENGTH = 100; const size_t DEPARTURE_LENGTH = 10; size_t AddStruct( Train * &trains, size_t n ); void Input( Train *trains, size_t i ); void Show( const Train *trians, size_t n ); void Free( Train * &trains, size_t n ); int main() { Train *city = nullptr; std::cout << "Enter number of trains: "; size_t n = 0; std::cin >> n; std::cout << std::endl; for ( size_t i = 0; i < n; i++ ) { AddStruct( city, i ); Input( city, i ); } Show( city, n ); Free( city, n ); return 0; } size_t AddStruct( Train * &trains, size_t n ) { Train *tmp = new Train[ n + 1 ](); for ( size_t i = 0; i < n; i++ ) tmp[i] = trains[i]; delete [] trains; trains = tmp; return n + 1; } void Input( Train *trains, size_t i ) { std::cout << "Enter number of train #" << i + 1 << ": "; std::cin >> trains[i].number; std::cout << "Enter location for train #" << i + 1 << ": "; trains[i].location = new char[LOCATION_LENGTH]; std::cin.ignore( 1, '\n' ); std::cin.getline( trains[i].location, LOCATION_LENGTH ); std::cout << "Enter departure for train #" << i + 1 << ": "; trains[i].departure = new char[DEPARTURE_LENGTH]; std::cin.getline( trains[i].departure, DEPARTURE_LENGTH ); } void Show( const Train *trains, size_t n ) { for ( size_t i = 0; i <n; i++ ) { std::cout << "Number: " << trains[i].number << '\n'; std::cout << "Location: " << trains[i].location << '\n'; std::cout << "Departure: " << trains[i].departure << '\n'; std::cout << std::endl; } } void Free( Train * &trains, size_t n ) { for ( size_t i = 0; i < n; i++ ) { delete [] trains[i].location; delete [] trains[i].departure; } delete [] trains; trains = nullptr; } 

The dialogue between the user and the program can be, for example,

 Enter number of trains: 3 Enter number of train #1: 1 Enter location for train #1: A Enter departure for train #1: A1 Enter number of train #2: 2 Enter location for train #2: B Enter departure for train #2: B2 Enter number of train #3: 3 Enter location for train #3: C Enter departure for train #3: C3 Number: 1 Location: A Departure: A1 Number: 2 Location: B Departure: B2 Number: 3 Location: C Departure: C3 

You can modify it to your liking.

  • Thank you, now it does not break. The question is, how can I initialize the input if before the Location and departure *? - Kairat Amanzharov
  • @KairatAmanzharov I did not understand your question. - Vlad from Moscow
  • Sorry, I meant if I had to use a char* reference for the task - Kairat Amanzharov
  • @KairatAmanzharov Do you mean that the Location and departure fields must have char * declarations? In this case, when entering values, you will first need to allocate the memory to which these pointers will point. For example, City [i] .Location = new char [199]; and only then read data from the stream. You should also remember to free this memory. Either you release this memory for these elements for each element in the cycle, or you should write a destructor for your structure. - Vlad from Moscow
 Train *City; /* ... */ for (int i = 0;i < n;i++) { input(City,count); 

The first mistake is here, there is no sense to look further Memory for the City not allocated, so everything falls. Not to mention what happens with this pointer in the input() function. But that's another story.