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
Related
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;
#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;
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.
So I need help with my code. For some reason it keeps crashing when I enter a number past 500,000. Here is the exact assignment.
Implement the Sieve of Eratosthenes and use it to find all prime
numbers less than or equal to one million. Use the result to
prove Goldbach's Conjecture for all even integers between four and
one million, inclusive.
Implement a function with the following declaration:
void sieve(int array[], int num);
This function takes an integer array as its argument. The array
should be initialized to the values 1 through 1000000. The
function modifies the array so that only the prime numbers remain;
all other values are zeroed out.
This function must be written to accept an integer array of any
size. You must should output for all primes numbers between 1 and
1000000, but when I test your function it may be on an array of a
different size.
Implement a function with the following declaration:
void goldbach(int array[], int num);
This function takes the same argument as the previous function
and displays each even integer between 4 and 1000000 with two
prime numbers that add to it.
The goal here is to provide an efficient implementation. This
means no multiplication, division, or modulus when determining if
a number is prime. It also means that the second function must find
two primes efficiently.
Output for your program:
All prime numbers between 1 and 1000000
and all even numbers between 4 and 1000000 and the two prime
numbers that sum up to it.
DO NOT provide output or a session record for this project!
And here is what I have so far. If anyone could help me that would be great.
#include <iostream>
using namespace std;
void sieve (int array[], int num);
int main()
{
int num;
cout << "Enter a number to calculate up to." << endl;
cin>> num;
if ( num < 2 )
return 0;
int array[num];
array[0]= array[1]= 0;
for ( int i= 2; i < num; ++i )
array[i]= i;
sieve(array,num);
for (int i=0; i<num; i++)
if (array[i] > 0)
cout << array[i] <<" "<<endl;
cout<<endl;
return 0;
}
void sieve( int array[], int num )
{
for ( int i= 0; i < num; ++i )
{
if ( array[i] != 0 )
{
for ( int j= i+i; j < num; j += i )
{
array[j]= 0;
}
}
}
}
The reason why your code crashes is that you're using VLA allocation for the array here
int array[num];
It's used to allocate num int elements of the stack, which is most probably too small to hold a million of int values.
You should note it's not a standard c++ feature, but an extension provided by a number of compiler implementations.
To fix this there are three alternatives:
You configure the stack size used for your program to be big enough to hold the number of int elements (this is OS dependend)
You use a std::vector<int> array(num); instead, that allocates these elements on the heap memory
You allocate the necessary memory on the heap yourself using int* array = new int[num]; and delete [] array; at the end of your program (I wouldn't recommend this solution, because it's prone to make silly mistakes regarding the proper memory management)
As I see this is an assignment, you need to write your own code, but I have a few ideas to reduce the amount of memory significantly.
Why don't you use array of bits instead ?
Do something like
#define IS_SET(x) (arr[(x)>>3] & (0x01 << ((x) & 0x07)))
#define SET(x) (arr[(x)>>3] |= (0x01 << ((x) & 0x07)))
and define arr as an array of char. This will make the memory utilization 8 folds down. For C++ you can use bool might not get you the lowest possible memory usage.
First clear out all the char elements. Then for each number set bits using SET(x) an once all marking is done. If IS_SET(x) evaluates false then x is prime.
Saves large amount of memory.
EDIT1:
Another trick to cut 50% of the memory required is not to retain space for the even numbers. Start with i=3 and always increment using i+=2 and mark the bit arrays. While reading do the same.
EDIT2:
If you can find a series which skips the integers which are multiple of two or three or both, then you can save around 30% more memory. In fact you can make such a series and skip storing and marking for the multiples of two and three or both.
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;
}