How to input 2D vector correctly? - c++

When I try to set and populate a 2D vector as follows, I couldn't input int numbers to them.
I try to input numbers usinga range-based for loop; but it doesn't finish after the expected number of loop cycles.
#include <iostream>
#include <vector>
using namespace std;
int main(){
int N;
vector<vector<int>> A(N,vector<int>(6));
cin>>N;
for(auto row_vec:A) {
for(auto x:row_vec) cin>>x;
}
return 0;
}
What is wrong with that code?
The following is my test input on the console:
[ec2-user#ip-10-0-1-187 atcoder]$ ./052
2
1 2
2 4
2 4

When running your code on linux you for example, I got:
terminate called after throwing an instance of 'std::length_error'
what(): cannot create std::vector larger than max_size()
If you encountered this, it should have been part of the question; if not, you still should have reported more on the actual behavior you saw; whether you could input some numbers for example. "it didn't finish" is an unclear problem description. You probably meant that it kept on asking for numbers, despite you having entered the amount of numbers that you expected it to ask for already?
With the above hint, the first thing should be to check the vector initialization. You declare the overall size N, but where do you initialize that? It is only set after it is used! So it tries to allocate a more or less random, unknown amount of memory using whatever value happens to be in the memory location where N will be stored.
You need to move the reading of N before the initialization of A:
cin>>N;
vector<vector<int>> A(N,vector<int>(6));
As a side note to your shown input, note that cin doesn't distinguish between space and line break as separator; so with the fixed size of 6 of the "second level" vector, with an overall size of 2, your loop would expect 12 inputs.
Additionally, the row_vec and x variables are created as copies of the respective parts of your vector - meaning that after your reading loop, the elements in A will still all be 0, since only copies of it were set.
You have to explicitly say that you want to take references to the parts of A by declaring the loop variables as auto &.
Full code for reading N times 6 variables (and printing them to see whether it worked):
#include <iostream>
#include <vector>
int main()
{
int N;
std::cin>>N;
std::vector<std::vector<int>> A(N,std::vector<int>(6));
for(auto & row_vec:A)
{
for(auto & x:row_vec)
{
std::cin>>x;
}
}
// print A to verify that values were set from input:
for (auto const & row: A) // note the use of const & to avoid copying
{
for (auto const & cell: row)
{
std::cout << cell << " ";
}
std::cout << "\n";
}
return 0;
}
One last note: It's recommended to not use using namespace std;

Related

Caught Fatal Signal 11 when solving vector problem

I have tried to solve the following problem: "n numbers are given. For every one of them, calculate the sum 1+(1+2)+(1+2+3)+...+(1+2+3+...+x) and output the results in a separate vector". I have gotten a formula for the sum and have implemented it into c++. The code seems to be working perfectly on vs code, but when I upload it to the website where I got the problem from I get 0 points, with the explanation: Caught fatal signal 11. I have read some articles but none of them have helped me crack the problem. Here is the code:
#include <iostream>
#define N 1000000
using namespace std;
int v[N], s[N];
int main()
{
int n, i;
cin >> n; // user inputs number of elements
for(i = 0; i < n; i++)
{
cin >> v[i]; // user inputs the elements
s[i] = v[i]*(v[i] + 1)*(v[i] + 2) / 6; // another vector is calculated using the formula
cout << s[i] << " ";
}
return 0;
}
Your problem is two fold. One, you're not using vectors, you're using C-style arrays. And two, you're running out of memory due to the size of your C-style arrays.
C-style arrays are allocated on the stack, and there is only limited memory on the stack. So if you allocate, say, two arrays of size, I don't know, 1000000, you might run into some memory issues.
On the other hand, C++ vectors are more modern, allow for dynamic resizing (useful for when you don't know how many elements you're going to have, I doubt you'll have 1000000), and it is also memory stored on the heap, giving you a lot more breathing room when it comes to memory.
Vectors work like this:
#include <vector>
std::vector<int> vec; // creates the vector
vec.push_back(5); // adds an element equal to 5 to the vector, vec size is now 1
vec.push_back(6); // adds an element equal to 6 to the vector, vec size is now 2
std::cout << vec[0]; // elements are accessed just like a C-style array

c++ runtime error when 2d array assigning another array value

#include<iostream>
#include<string>
#include <cstring>
using namespace std;
bool b[200][200];
int a[46];
int test_cases;
int n;
int m;
int first;
int second;
int main()
{
cin>>test_cases;
while(test_cases--){
cin>>n;
cin>>m;
for (int i=0;i<2*m;i++){
cin>>a[i];
}
for (int j=0;j<m;j++){
first=a[2*j];
second=a[2*j+1];
b[first][second]=true;
}
}
return 0;
}
Hello. Runtime error seems to occur on the last code 'b[first][second]=true;'
I tried couple of changes and i found if i turn 'b[first][second]=true;' into 'b[second][first]=true;' error doesn't occur, which is simply to change the order of indices.
There is not a possibility of "out of range error" because memory size of b is [200][200] and range of results of a[*] is from 0 to 10.
I can't figure out where the problem is coming from and i need help. Thank you.
There is not a possibility of "out of range error" because memory size of b is [200][200] and range of results of a[*] is from 0 to 10.
The world is littered with buggy code because people made assumptions like this. The first thing you should do is prove this correct. That's as simple as placing something like:
if (first < 0 || first > 199 || second < 0 || second > 199) {
cerr << "Violation, first = " << first << ", second = " << second << "\n";
exit(1);
}
immediately before your line that sets the b[][] element to true.
As an aside, it would also be prudent to check other array accesses as well. Since we don't have your test data, we have no idea what value will be input for n or m but, since those values can result in undefined behaviour (by accessing beyond array bounds), they should also be scrutinised.
If you wanted to be sure that those didn't cause problems, you could dynamically allocate to the correct size as necessary. For example, once you've gotten m from the user:
int *a = new int[m*2];
// Use it as you wish, elements <0..m*2-1> inclusive.
delete [] a;

How to do array

I am trying to learn how to code array.. (i am still a beginner in programming just starting to learn last year) i don't know what's wrong in my code.. the problem is to take 5 integer inputs from user and store them in an array. Again ask user to give a number. Now, tell user whether that number is present in array or not. but my code doesn't recognize my else. Even if i put a number that isn't present in my array it still says "It is present".
int main(){
int num[4];
int i;
int comp;
cout<<"Please input 5 numbers: "<<endl;
for (i=0;i<=4;i++)
{
cin>>num[i];
}
cout<<"Now please input another number to compare: ";
cin>>comp;
if (num[i]=comp){
cout<<"The number you inputted is present in the array";
}
else {
cout<<"It is not present in the array";
}
}
the problem is to take 5 integer inputs from user and store them in an array.
Let's start declaring an array that can hold up to 5 integers.
int numbers[5] = {};
// ^^^ This should be the size of the array, not the maximum index
Since C++11, you can use a proper standard container
std::array<int, 5> numbers{};
Note that in both snippet I initialized those arrays.
Now, the loop that reads all the elements of the array can be written as
for (int i = 0; i < 5; ++i) {
// ^
}
Or use a ranged for
for (auto & number : numbers)
{ // ^^^^^^^^ Loops through the array using `number` as a reference to each element
std::cin >> number;
if (!std::cin) {
std::cerr << "An error occurred while reading.\n";
break;
}
}
The posted loop also goes from 0 to 4 (included), but the array declared in that snippet only has 4 elements, so that it is accessed out of bounds and the program has undefined behaviour.
Another problem, is that the program doesn't check
whether that number is present in array or not
It does only one "check", instead of a loop:
if ( num[i] = comp) {
num[i] = comp is an assignment, not a comparison (you should adequately rise your compiler warning level) and an assignment to an element outside the array (i has value 5, now). It's the result of this assignment, comp, that is used as a condition, which means that the branch is executed whenever comp is not 0.
Or, at least, this is the most likely outcome, given that that assignment is UB too and the compiler could genereate whatever code it decides or your program could seg-fault due to that access out of bounds.
#include "stdafx.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
int num[4];
int i;
int comp;
int coo;
int flg=0;
std::cout<<"Please input four numbers: "<<"\n";
for (i=0;i<=3;i++)
{
std::cin>>num[i];
}
std::cout<<"Now please input another number to compare: ";
std::cin>>comp;
for (i=0;i<=3;i++)
{
if (num[i]==comp){
flg = 1;
break;
}
}
if (flg) {
printf("The number you inputted is present in the array.\n","%s");
} else {
printf("It is not present in the array\n", "%s");
}
std::cin>>coo;
return 0;
}
Basically, you ommitted to loop through all the array members when comparing the array with the number to be compared and I just added the loop in so that it looped through all array members and compared it with the input number.

creating mxn 2D array in c++ without using any external library

I am a beginner to C++ syntax. Now, I need to create an mxn 2D array in C++ to use it in another project. I have looked at other answers which involve using tools like vector, etc. Many tools are not working on my Visual Studio 15 i.e. for vector I can not define with std::vector without a message like vector is not in std. So, I have wrote the following code:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
int i; int j; int row[5][10] = {};
for (int j = 0; j < 10;)
for (int i = 0; i < 5;)
{
row[i][j] = 500;
int printf(row[i][j]);
i++;
j++;
cout << "Array:" << row[i][j] << endl;
}
return 0;
}
Surely, this is not the correct syntax. So the output is beyond my expectation. I want to create an m*n array with all the elements being the same integer; 500 in this case. That is, if m=3, n=2, I should get
500 500 500
500 500 500
There's a couple things wrong with your current code.
The first for loop is missing curly brackets
You're redefining int i and int j in your for loop. Not a complilation issue but still an issue.
You're using printf incorrectly. printf is used to output strings to the console. The correct line would be printf("%d", row[i][j]);
If you want to use a vector, you have to include it using #include <vector>. You can use a vector very similar to an array, but you don't have to worry about size.
You seem to be learning. So, I did minimal correctios to make it work. I suggest you to make modifications as per your needs.
#include <iostream>
using namespace std;
int main()
{
int row[5][10] = {};
for (int j = 0; j < 10; j++) {
for (int i = 0; i < 5; i++) {
row[i][j] = 500;
cout << row[i][j] << " ";
}
cout << endl;
}
return 0;
}
Care and feeding of std::vector using OP's program as an example.
#include <iostream>
#include <vector> // needed to get the code that makes the vector work
int main()
{
int m, n; // declare m and n to hold the dimensions of the vector
if (std::cin >> m >> n) // get m and n from user
{ // m and n are good we can continue. Well sort of good. The user could
// type insane numbers that will explode the vector, but at least they
// are numbers.
// Always test ALL user input before you use it. Users are malicious
// and incompetent <expletive delteted>s, so never trust them.
// That said, input validation is a long topic and out of scope for this
// answer, so I'm going to let trapping bad numbers pass in the interests
// of keeping it simple
// declare row as a vector of vectors
std::vector<std::vector<int>> row(m, std::vector<int> (n, 500));
// breaking this down:
// std::vector<std::vector<int>> row
// row is a vector of vectors of ints
// row(m, std::vector<int> (n, 500));
// row's outer vector is m std::vector<int>s constructed with
// n ints all set to 500
for (int j = 0; j < n; j++) // note: j++ has been moved here. This is
// exactly what the third part of a for
// statement is for. Less surprises for
// everyone this way
// note to purists. I'm ignoring the possible advantages of ++j because
// explaining them would muddy the answer.
// Another note: This will output the transverse of row because of the
// ordering of i and j;
{
for (int i = 0; i < m; i++) // ditto I++ here
{
// there is no need to assign anything here. The vector did
// it for us
std::cout << " " << row[i][j]; // moved the line ending so that
// the line isn't ended with
// every column
}
std::cout << '\n'; // end the line on the end of a row
// Note: I also changed the type of line ending. endl ends the line
// AND writes the contents of the output stream to whatever media
// the stream represents (in this case the console) rather than
// buffering the stream and writing at a more opportune time. Too
// much endl can be a performance killer, so use it sparingly and
// almost certainly not in a loop
}
std::cout << std::endl; // ending the line again to demonstrate a better
// placement of endl. The stream is only forced
// to flush once, right at the end of the
// program
// even this may be redundant as the stream will
// flush when the program exits, assuming the
// program does not crash on exit.
}
else
{ // let the use know the input was not accepted. Prompt feedback is good
// otherwise the user may assume everything worked, or in the case of a
// long program, assume that it crashed or is misbehaving and terminate
// the program.
std::cout << "Bad input. Program exiting" << std::endl;
}
return 0;
}
One performance note a vector of vectors does not provide one long block of memory. It provides M+1 blocks of memory that may be anywhere in storage. Normally when a modern CPU reads a value from memory, it also reads values around it off the assumption that if you want the item at location X, you'll probably want the value at location X+1 shortly after. This allows the CPU to load up, "cache", many values at once. This doesn't work if you have to jump around through memory. This means the CPU may find itself spending more time retrieving parts of a vector of vectors than it does processing a vector of vectors. The typical solution is to fake a 2D data structure with a 1D structure and perform the 2D to 1D mapping yourself.
So:
std::vector<int> row(m*n, 500);
Much nicer looking, yes? Access looks a bit uglier, though
std::cout << " " << row[i * n + j];
Fun thing is, the work done behind the scenes converting row[j][i] to a memory address is almost identical to row[j*n+i] so even though you show more work, it doesn't take any longer. Add to this the benefits you get from the CPU successfully predicting and reading ahead and your program is often vastly faster.

Why is this code showing segmentation error on codechef?

Please i am stuck at this question for half an hour and can't find why the error comes?
Problem code : test
Life, Universe and Everything
#include<iostream>
using namespace std;
int main()
{
int a[20],i;
cin>>a[0];
for(i=1;a[i-1]!=42;i++)
{
cout<<a[i]<<"\n";
cin>>a[i];
}
return(0);
}
Your code tries to access non-existing array elements, which causes segfault. You should stop your loop before the array index gets larger than the length of the array minus 1:
int a[20];
for (i = 1; i < 20 && a[i - 1] != 42; i++)
{
// ...
}
Apart from limit problem, your printing elements without initializing them
//for i = 1, a[i] is uninitialized
cout<<a[i]<<"\n";
On accessing a local variable (like this), you're likely to get garbage value.
This might be better substitute for what you are trying to do:
int a[20],i;
for(i=0;i < 20;i++)
{
cin>>a[i];
if (a[i] == 42)
break;
cout<<a[i]<<"\n";
}
You are trying to print the uninitialized data...
#include<iostream>
using namespace std;
int main()
{
int a[20],i;
cin>>a[0]; // a[0] uninitialized
for(i=1;a[i-1]!=42;i++)
{
cout<<a[i]<<"\n";
cin>>a[i];
}
return(0);
}
In the for loop get the data first and then print it.Your array size is 20 but you are trying to write upto 42.
You use array values before initializing them. C++ doesn't initialize non-static arrays for you unless you tell it to, so $DEITY knows what's in there. And technically, whatever's in there could cause an exception...or any number of other things. (For ints, on an x86 machine, that's actually highly unlikely. But elsewhere, it's possible.)
The user can enter more than 20 numbers. That's really just a special case of the more general problem, though: You allow unknown number of entries, but aren't able to accept them all without crashing.
If you don't know beforehand how many objects there will be, use a vector.
#include <iostream>
#include <vector>
using namespace std;
int main()
{
std::vector<int> a;
int entry;
cin>>entry;
// Oh, yeah. This. You really, *really* want to check `cin`.
// Otherwise, if the user decided to type "i like cheese", you'd loop
// forever getting zeros while cin tried to parse a number.
// With the array, that'd typically cause a segfault near instantly.
// With a vector, it'll just eat up all your CPU and memory. :P
while (cin && entry != 42) {
a.push_back(entry);
cout << entry << "\n";
cin >> entry;
}
return 0;
}