My program stops with no errror, what did I do wrong? - c++

I have no idea why, but my code just stops at the 2nd for loop in the cin line, if it loops more than 1 time.
Can you help me?
This is my code:
#include <iostream>//Julianne
using namespace std;
int main(){
int a;
cin >> a;
int bezorgen[a];
int afhalen[a];
for (int i = 0; i < a; i++){
cin >> bezorgen[i];
}
for (int j = 0; j < a; j++){
cin >> afhalen[j];
}
return 0;
}
P.S. Sorry for my grammar mistakes.

C++'s declaration
int name[N] is only valid when N is constant. For dynamic sized array (which is in your case dynamic, cause array size comes from user input) you can use:
C++ std::vector<int>
int *name = new int[a]
First one is the list, not an array. So you need to .push_back elements before they can be accesed.
Second one is an array, and accessed just like common array. Be careful with that, because you need to free memory when it's not needed anymore, call delete [] name; at the end of your program for every new type[size] you've done.

Related

Beginner C++ Array

I am new to C++. Below is code to input and display an array -- a simple thing to understand how things work.
int main() {
int N, i;
int A[N];
cin >> N;
for (i = 0; i < N; i++) {
cin >> A[i];
}
for (i = 0; i < N; i++) {
cout << A[i];
}
return 0;
}
The input is:
4
1 2 3 4
and output is:
12
I have corrected my code to:
int N, i;
cin >> N;
int A[N];
This correctly displays the array.
What exactly happened? Should N have a value before initializing A[N]? But then why didn't my initial code work? Is this something to do with Hierarchy? If so, how can I get my priorities right?
If N is initialized as a large value, N has an input of specific number next, if so how come even if N=9, the output remains same: 12?
Should N have a value before initializing A[N]
Yes. It should. It should even have a value before declaring A[N].
How else would the runtime know how much space to allocate for A?
To answer your question.
int N, i;
Here, you declare N, but because you don't assign a value to N, N is uninitialized and can hold any value (probably some old program's value.)
And you create an array with N, which will lead to some unexpected behavior. (for example, a stack overflow could happen when N is too big)
And:
The size of arrays in C++ has to be known at compile-time. That means when you compiler compiles the program, the array's size has to be known.
In your case, you know n (the size) at runtime, which means only when you run the program, you know the value of n, which is the size.
Your code run because (probably) gcc compiler does have an extension for this to happen, but because this is not standard C++, I would recommend not using it.
C++ has a solution for runtime array, and that is std::vector in the <vector> header.
You just need to change:
cin >> N;
int A[N];
to:
std::cin >> n;
std::vector<int> A(N);
note: using namespace std; is bad, so don't use it.
In C++, the size of an array must be a compile time constant. So the following code is incorrect:
int N = 10;
int arr[N]; //incorrect
The correct way to write this would be:
const int N = 10;
int arr[N]; //correct
For the same reason the following code is incorrect in your given code snippet:
int N, i; //both N and i are **unitialized**(meaning they have **garbage value**)
cin >> N; //this is fine. This takes input from user and put it in N
int A[N]; //incorrect because N must be a constant expression
Also note that your original question used the garbage value of N to create an array. This is why it is advised that always initialize built in type in block/local scope.

C++ struct questions

I've googled relates to struct and I was able to see how they are used; however, I couldn't clearly figure out some of them.
Let's say I have 2 structs
struct Student {
int age;
int height;
};
struct School {
Student information;
};
and let's say I want to handle information School[i].Student[j].age or height based on input file.
int main() {
int school_number = 20;
int student_number = 50;
School school[school_number-1]; // is this the correct way to create it? since [0] is the first school
for (int i=0; i < school_number; i++) {
for (int j=0; j < student_number; j++) {
getline(file, line); // let's say the line has student's age and height.
istringstream c(line);
c >> school[i].information[j].age >> school[i].information[j].height;
}
}
}
I thought this would do the job, but I'm getting no match for 'operator[]' (operand types are 'Student' and 'int') compile error.
What am I missing?
when it's just student,
Student info[student_number-1];
for (int i=0; i < student_number; i++) {
getline(file, line);
istringstream c(line);
c >> information[i].age >> information[i].height;
}
this one works without problem, but I am still not sure what I need to do for 2 structs, where one is calling other one.
One more question,
while I was searching, I see lots of
School *id = new School[school_number-1];
something like this. How does this different from
School school[school_number-1];
this one?
I see a pointer, so I'm pretty sure it does something, but based on how they are used, they look pretty much same.
edit : I've tried little bit, but still not sure how to use vector in this case.
for the above case,
int main() {
vector[Student] student;
int school_number = 20;
int student_number = 50;
School school[school_number-1]; // is this the correct way to create it? since [0] is the first school
for (int i=0; i < school_number; i++) {
for (int j=0; j < student_number; j++) {
getline(file, line); // let's say the line has student's age and height.
istringstream c(line);
c >> school[i].information[j].age >> school[i].information[j].height;
}
}
}
if I call
vector[Student] student;
how can I modify the line
c >> school[i].information[j].age >> school[i].information[j].height;
with the variable student I just created?
If you wanted to declare an array, that must have a const size. What you probably wanted is std::vector<Student>
struct School {
Student information;
};
In this code struct School would contain only one Student object, so school[i].information[j] fails. (It attempts to call operator[] on the Student object school[i].information, which is not defined.)
School school[school_number];
(a C-style array) is not valid C++, because school_number is a variable, and C-style arrays can only have a constant number of items. They are also not recommended in modern C++.
std::array<School, 20> school;
is the recommended way to create an array of 20 School objects.
Because in this code school_number has a fixed value, it could instead be defined as
constexpr int school_number = 20;
and then it can be used with std::array or the C-style array.
Also the array would need to have school_number items, and not school_number-1. school_number-1 is however the index of its last item (because they are counted from 0, when indexing).
For an array with a variable number of items, std::vector can be used:
std::vector<School> school(school_number);
Or alternately, an empty vector is created with
std::vector<School> school;
and then School objects are inserted into it with
school.push_back(sch);
So the program could be written like this:
struct Student {
int age;
int height;
};
struct School {
std::vector<Student> information; // School has array of students
};
int main() {
int school_number = 20;
int student_number = 50;
std::vector<School> schools;
for(int i = 0; i < school_number; i++) {
School school; // first create School object, and then insert it into schools array
for(int j = 0; j < student_number; j++) {
Student student; // same for Student object
getline(file, line);
istringstream c(line);
c >> student.age >> student.height;
school.information.push_back(student);
}
schools.push_back(school);
}
}
School *id = new School[school_number-1];
creates an array of school_number-1, and returns a pointer to it. The pointer needs to be manually freed after use with
delete[] id;
It returns a pointer because the memory gets allocated on the heap.
std::vector<School> does this automatically, and can also increase/decrease the size of the allocated memory when items are inserted/removed from the array.
The way you have declared school it has only one student. You probably want a vector of students instead of one student in your school.
When you declare an array the number that you put inside the bracket is the length of the array. If the length of the array is n you can access elements 0 to n-1 when using the array. When declaring it, you should put n in the brackets though.
Pointers and arrays are very close concepts and in many situations interchangeable. If you have little C experience, sticking with arrays is safer.
School *id = new School[school_number-1];
School school[school_number-1];
the first one is declared on heap memory and the second one is declared on stack. You must delete the first one as soon as you done with it to avoid memory leak.

using delete[] in main when new int [] was declared in a function

My first job is this:
"The first function, readNumbers, is to read a set of 10 numbers from std::cin and use them to initialise a dynamically allocated array of int of length 10 (dynamic allocation is on the heap). The function must return a pointer to the array. You may assume that the input will be 10 integer values and nothing else."
which is fine, however i need to then:
"The main function for this problem must call your readNumbers function, then pass the new array to your printNumbers function and finally delete the array."
However i am unsure of how to handle the delete in main, when the new int [] has been declared in a function. here is the relevant parts of my code.
int *readNumbers(){
int * numbers;
numbers = new int [10];
for (int i = 0; i < 10; i++){
int userinput;
cin >> userinput;
*(numbers+i) = userinput;
}
return numbers;
}
and
int main(){
printNumbers(readNumbers(),10);
delete[] numbers;
}
obviously the delete[] request in main is a syntax error, i am unsure of the solution.
You need to assign the result of readNumbers() to a variable, then you can delete it.
int main() {
int *numbers = readNumbers();
printNumbers(numbers, 10);
delete[] numbers;
return 0;
}

C++ segmentation fault array

In C++ I get a segmentation fault after telling the program how big the array should be (x).
Why is this happening and how do I fix this?
#include <iostream>
using namespace std;
int main()
{
int x;
cin >> x;
int array[x];
for (int *j=array; j; j++)
{
*j=0;
}
for (int *i=array; i; i++)
{
cin >> *i;
}
cout << array[3] << endl;
}
Your loop conditions are wrong.
for (int *j = array; j; j++)
and
for (int *i=array; i; i++)
will not stop at the end of the array, as the condition j (i) is true when traversing the array (i.e., to be false, the pointer needs to be nullptr). In fact, pointer arithmetic past the array boundary plus one results in undefined behaviour. Your stopping condition should be
i < array + x;
Moreover, variable length arrays are an extension and not support by the C++ standard. Use new[] instead to allocate memory, as #Joshua Byer pointed out.
int * array;
array= new int [x];
http://www.cplusplus.com/doc/tutorial/dynamic/
The conditions used in your loops are incorrect.
eg. for (int *j = array; j; j++) even though j will eventually reach the end of the array but will still never evaluate to false (allowing the loop to finish). On top of this it means you will iterate to past the end of the array and move into Undefined Behaviour, this is probably why you are seeing the segfault.
you either need to do the following (super gross solution!!!! also not C++ standard supported):
for (int i = 0, *j = array; i < x; i++, j++)
which will increment a counter and check the array at the same time as incrementing your pointer.
OR
USE VECTORS
std::vector is a much easier way to do what you are doing.
int arraySize;
cin >> arraySize;
std::vector<int> array(arraySize, 0);
for (int i=0; i < arraySize; i++)
{
cin >> array[i];
}
cout << array.at(3) << endl;
Here is a live example.
Within a for statement, the second expression should terminate the loop by evaluating to false. In this case however you never terminate the loop:
for (int *j=array; j; j++)
Instead do:
for (int *j=array; j < array + x; j++)
The expression array + x (by pointer arithmetic) means one element past the end of the array.
The above goes for both of the loops.

Program declaring variables by itself

I am still a ... novice, in c++.
I don't know the name of what I am looking for but
I 've been searching a lot but can't seem to find the answer to following question:
I want to write a program that would declare demanded number of variables.
Example:
int a;
cin>>a;
Now if "a" is 5 (or any other number), I want program to declare 5 more variables,
Names do not matter but let's say...n1,n2,n3,n4,n5.
I've tried array and for loop but can't get it to work.
I got answer on Croatian forum (forum.hr) but the forum is currently offline, so I had no
time to try it out...
It was about using heap instead of stack
Thx in advance
C++ has container classes for this purpose. In particular, you want a vector:
std::vector<int> a(size);
for (int i = 0; i < a.size(); ++i)
std::cin >> a[i];
Declares a vector a of integers of some size and reads its elements, one by one.
If this is C++, the best you can do is using std::vector as it will manage the memory for you.
you can store them in an array:
int a;
cin >> a;
int *number = new int[a]; // allocate an array of size a
for (int i = 0; i < a; i++) {
number[i] = 5 + i; // set your numbers to anything here
}
delete[] number; // otherwise you have memory leak
or better use a vector:
vector<int> number(a);
// iterate with a normal for loop
for (int i = 0; i < number.size(); i++) {
number[i] = 5 + i;
}
..
// or use iterators
for (vector<int>::iterator it = number.begin(); it != number.end(); ++it) {
cout << *it << endl;
}
so you don't have to manage memory.