This is quite common question and I tried reading the solutions but none of them seem to fix my problem. Here is the code I wrote which I know is quite a mess because I am a newbie at C++.
#include<iostream>
#include<string>
#include<iomanip>
#include<set>
#include<queue>
#include<cmath>
#include<algorithm>
#include<vector>
#include<limits.h>
#include<math.h>
#include<map>
#include<cstring>
using ll = long long;
const int N = 2e6+6;
int main(){
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
int n,m;
std::cin >> n >> m;
std::vector<std::array<int,3>> edges;
int exist[n][n];
memset(exist,0,sizeof(exist));
for(int i = 0; i < m;++i){
int a,b;
char c;
std::cin >> a >> b >> c;
--a,--b;
edges.push_back({a,b,c-'a'});
exist[a][b] = exist[b][a] = 1;
}
std::vector<int> adj[N];
std::map<std::pair<int,int>,int> nodes;
int node = 0;
for(int i = 0; i < m;++i){
for(int j = 0; j < m;++j){
if(i == j)
continue;
if(edges[i][2] != edges[j][2])
continue;
int a = edges[i][0];
int b = edges[i][1];
int c = edges[j][0];
int d = edges[j][1];
if(nodes[{a,c}] == 0)
nodes[{a,c}] = ++node;
if(nodes[{b,d}] == 0)
nodes[{b,d}] = ++node;
if(nodes[{a,d}] == 0)
nodes[{a,d}] = ++node;
if(nodes[{b,c}] == 0)
nodes[{b,c}] = ++node;
adj[nodes[{a,c}]].push_back(nodes[{b,d}]);
adj[nodes[{b,d}]].push_back(nodes[{a,c}]);
adj[nodes[{a,d}]].push_back(nodes[{b,c}]);
adj[nodes[{b,c}]].push_back(nodes[{a,d}]);
}
}
int start = nodes[{0,n-1}];
int ans = 1e9+7;
std::queue<int> q;
q.push(start);
std::vector<int> dist(node+1,-1);
dist[start] = 0;
std::vector<bool> visited(node+1,false);
visited[start] = true;
auto it = nodes.begin();
while(!q.empty()){
int cur_node = q.front();
q.pop();
for(int i = 0; i < (int)adj[cur_node].size();++i){
int next_node = adj[cur_node][i];
if(!visited[next_node]){
q.push(next_node);
visited[next_node] = true;
dist[next_node] = dist[cur_node] + 1;
}
}
}
for(int i = 0; i < n;++i){
for(int j = 0; j < n;++j){
int node = nodes[{i,j}];
if(node == 0)
continue;
if(dist[node] == -1)
continue;
if(i == j || (exist[i][j] == 1)){
ans = std::min(ans,dist[node]);
}
}
}
if(ans == 1e9+7)
ans = -1;
std::cout << ans << "\n";
}
This program gives segmentation fault even before entering main and I tried using gdb which also says that error is on the line int main() . I don't understand at all what is happening, and also I tried running the program on C++ 14 and C++ 17 and it runs fine but I am using C++ 11 and it compiles successfully but doesn't run. Please help me.
You’re allocating over two million std::vectors in your code in stack. Usually the stack isn’t very big so that most definitely will go over the reserved space and cause issues. The allocation for local objects happens before any code in the function is run so it will look like it crashes in the function but before any of your code is run.
std::vector<int> adj[N];
You’ll need to allocate it dynamically if you need that many vectors.
First, this is not valid C++:
int n;
cin >> n;
int exist[n][n]; // <-- not valid C++
Arrays in C++ must have their sizes denoted by a compile-time expression, not a runtime value. C++ does not support variable-length arrays.
The code compiled, since there are some compilers that by default, have support for this. But it still is not supported by the C++ language specification. For example, the Visual C++ compiler does not support this syntax. If you attempted to compile your code using Visual C++, you would be greeted with the appropriate error message.
Even if this is supported, a large value of n could potentially blow the stack memory, since the stack memory is limited.
Then the second issue is that you have this:
std::vector<int> adj[N];
If N is large, that is an array of N std::vector<int>. Again, this will more than likely exhaust the stack memory.
One solution is to use std::vector<std::vector<int>>:
std::vector<std::vector<int>> exist(n, std::vector<int>(n));
//...
std::vector<std::vector<int>> adj(N):
Since the vector gets its memory from the heap, the stack memory exhaustion issue goes away.
Related
I don't understand why this is happening.
The Code is working fine, but it won't show output in my system when I take a large array size and on the other side it gives the correct output in the online compiler.
It works fine and shows output in my system if I take a small array size.
#define N 805
Here is a code in C++ language.
#include<bits/stdc++.h>
using namespace std;
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
#define M 1000000007
#define N 805
#define ll long long int
void init_start(){
fast_io;
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
}
int main()
{
init_start();
int n, k, limi;
cin>>n>>k;
int n_arr[N][N];
int k_arr[N][N];
for (int i = 0; i < N; i++)
{
k_arr[i][0]=0;
k_arr[0][i]=0;
}
int mini = -1, maxi = 1000000000, mid;
bool check;
limi = ((k*k) / 2) + 1;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
cin >> n_arr[i][j];
}
}
while((mini + 1) < maxi)
{
mid = (mini + maxi) / 2;
for (int i = 0; i < n; ++i)
{
for (int j = 0; j < n; ++j)
{
k_arr[i+1][j+1] = k_arr[i+1][j] + k_arr[i][j+1] - k_arr[i][j];
if(n_arr[i][j] > mid)
{
k_arr[i+1][j+1]++;
}
}
}
check = false;
for (int i = 0; i < n-k+1; ++i)
{
for (int j = 0; j < n-k+1; ++j)
{
if ((k_arr[i+k][j+k] + k_arr[i][j] - k_arr[i][j+k] - k_arr[i+k][j])<limi)
{
check = true;
}
}
}
if (check)
{
maxi = mid;
}
else
{
mini = mid;
}
}
cout << maxi << endl;
return 0;
}
int n_arr[N][N];
int k_arr[N][N];
I suspect your local environment is configured with a smaller stack size that the online one. With N set to 805, and with 32-bit integers, that's going to consume about 5M of stack, quite a lot.
You may want to think about using the heap, which is usually less restrictive (new and delete). An easy solution is to keep the first dimension on the stack (805 pointers is not too bad) but use the heap for the second dimension, something like:
int *n_arr[N], *k_arr[N];
for (int i = 0; i < N; ++i) {
n_arr[i] = new int[N];
k_arr[i] = new int[N];
}
// Use them here as you currently do, e.g., n_arr[42][99].
for (int i = 0; i < N; ++i) {
delete [] n_arr[i];
delete [] k_arr[i];
}
A better solution for C++ would probably be to use std::vector, or find/create a heap-based matrix class of some description.
#include<bits/stdc++.h>
Avoid abusing implementation defined headers. The purpose of this header is to use in pre-compiled headers.
using namespace std;
Avoid using this in the namespace scope. Prefer using the scope resolution operator instead.
#define fast_io ios_base::sync_with_stdio(false);cin.tie(NULL);
Avoid obfuscating the program like this. Prefer using a function instead.
#define M 1000000007
#define N 805
Avoid using macros for constants. Prefer (constant) variables instead.
#define ll long long int
Avoid using macros for type aliases. Prefer typedef/using instead.
Just avoid using macros altogether unless there are no better alternatives (and there usually is).
Also, prefer to avoid using type aliases altogether except for template purposes. long long isn't that much to type, and it is immediately obvious to a reader what type it is.
The size available for automatic variables is typically very limited on most systems. You should avoid large automatic objects since those will likely result in a... stack overflow.
int n_arr[N][N];
This is an automatic variable. And it is huge. It is very likely to overflow the stack on some systems. Avoid doing this.
For this program, the simplest solution is to use static storage instead of automatic.
I have just started coding in C++ and I am using codeblocks. My build log is giving me 0 errors and 0 warning but I do not know why when I run it, it is giving me no result in the terminal.
Terminal Window Result:
Process returned -1073741571 (0xC00000FD) execution time : 1.252 s
Press any key to continue.
my code:
#include <iostream>
#include<math.h>
using namespace std;
int main() {
int n;
cin>>n;
int a[n];
for(int i = 0; i <n ; i++){
cin>>a[i];
}
const int N = pow(10, 6);
int idx[N];
for(int i = 0; i< N; i++){
idx[i] = -1;
}
int minidx = INT_MAX;
for(int i = 0; i<n; i++){
if(idx[a[i]] != -1){
minidx = min(minidx, idx[a[i]]);
}
else{
idx[a[i]] = i;
}
}
if (minidx == INT_MAX){
cout<<"-1"<<endl;
}
else{
cout<<minidx+1<<endl;
}
return 0;
}
Please help me in finding my mistake in the code.
This:
int n;
std::cin >> n;
int a [n];
for (int i = 0; i < n ; i++) {
std::cin >> a [i];
}
is bad practice. Don't use VLAs whose size you don't know at compile time. Instead, if I guess correctly that this is some Competitive Programming problem, you'll probably know what the max size will be as stated in the problem. So, do it this way instead:
int n;
std::cin >> n;
constexpr int max_size = 1000000;
int a [max_size];
for (int i = 0; i < n; i++) {
std::cin >> a [i];
}
However, even doing it this way will crash your program anyway. This is simply because of stack overflow when you declare an array that size inside a function. For slightly smaller sizes however, that would be okay. Just don't use VLAs the way you're using them.
One solution is to use a standard container like std::vector as the allocation takes place on the heap. Note that using std::array will crash too as the allocation is not on the heap.
Another solution is to make your array a global. This way you can increase to sizes well over 1e6. Not really recommended though.
In your code above, irrespective of what the size n for array a is (even if it's a fairly small size to fit on the stack), your code will definitely crash when you declare the array idx [1000000]. Reason is the same, stack overflow.
Also, please post indented code and use good indentation practices.
I get a segmentation fault when I try to run the code below. I've tried commenting out bits of the code, and found that the while loop with the condition j < is_prime.size() is the culprit. This is puzzling to me because I perform the same check between the same values in the for loop above it, but do not get a segmentation fault.
Could someone explain to me what's the issue here?
I'm using GCC 4.8.2 on Linux 64.
#include <bitset>
#include <iostream>
using namespace std;
const size_t max_pandigital = 987654321;
int main()
{
bitset<max_pandigital/3> is_prime;
is_prime.set(); // assume all numbers are prime
is_prime[0] = false; // 1 is not prime
for(size_t i = 1; i < is_prime.size(); i++) {
if(is_prime[i]) {
int n;
if(i%2 == 0) n = 3*i+1;
else n = 3*i+2;
size_t j = i;
if(j%2 == 0) j += n-2;
else j += n+2;
while(j < is_prime.size()) {
is_prime[j] = false;
if(j%2 == 0) j += n-2;
else j += n+2;
}
}
}
//cout << is_prime[899809363/3] << endl;
}
Edit: I implemented some of the changes suggested. Here's a working version - runs in ~13s. I think the biggest bottleneck is allocating the 42MB for the bool vector. Thanks!
#include <iostream>
#include <vector>
using namespace std;
const size_t max_pandigital = 987654321;
int main()
{
vector<bool> not_prime(max_pandigital/3);
not_prime[0] = true; // 1 is not prime
for(size_t i = 1; i < not_prime.size(); i++) {
if(~not_prime[i]) {
int n;
if(i%2 == 0) n = 3*i+1;
else n = 3*i+2;
size_t j = i;
if(j%2 == 0) j += n-2;
else j += n+2;
while(j < not_prime.size()) {
not_prime[j] = true;
if(j%2 == 0) j += n-2;
else j += n+2;
}
}
}
cout << not_prime[899809363/3] << endl; // prime
cout << not_prime[100017223/3] << endl; // pseudoprime
}
If the commented-out is commented in, and I run your code then I get a segfault due to stack overflow. (Even if the code remains commented out though, the stack still overflowed, which explains what you are seeing).
Typical systems default to a stack size on the order of 1 megabyte; but your bitset requires about 40 megabytes of storage.
To fix this you could either:
dynamically allocate your bitset
use a different container such as vector<bool>
tell your environment to use a larger stack size
An example of dynamic allocation might be:
unique_ptr< bitset<max_pandigital/3> > ip { new bitset<max_pandigital/3> };
auto &is_prime = *ip;
and the rest of the code the same.
You are not guaranteed to segfault when you mess up a reference or fencepost! The behavior is "undefined", and can be quite troublesome to track down. Use something like 'valgrind' to find the exact first moment of badness.
I wrote this knapsack problem solution in c++ however when I run it, it gives me segmentation fault
I have tried everything and my compiler will always give me the segmentation fault error.
#include<iostream>
#include<algorithm>
int knapsack(int v[],int w[],int n,int W)
{
int V[n][W];
for(int i = 0; i<=W;i++)
{
V[0][i] = 0;
}
for(int i = 0; i <= n; i++){
for(int j = 1; j<=W; j++)
{
if(w[i]<=W)
{
V[i][j] = std::max(V[i-1][j], v[i]+V[i-1][j-w[i]]);
}
else
{
V[i][j] = V[i-1][j];
}
}
}
return V[n][W];
}
int main()
{
int v[4] = {10,40,30,50};
int w[4] = {5,4,6,3};
int n = 3;
int W = 10;
std::cout<<"item value:"<<knapsack(v,w,n,W);
}
Don't use VLAs. The size of an array must be known at compile time, else it's not standard C++. Those are compiler extensions that are not portable and introduce some hidden costs.
Array indices go from 0 to length-1. in you loop
for(int i = 0; i<=W;i++)
i can reach W, then V[0][W] is out of bounds which causes the seg fault. You have to use < instead of <=:
for(int i = 0; i < W; i++)
n should probably be 4, if it's meant to represent the size of the array, a std::vector would make your life easier here, because a vector knows it's size
In general don't use C-style arrays or raw pointers at all in this day and age, use std::vector instead.
int V[n][W];
for(int i = 0; i<=W;i++)
{
V[0][i] = 0;
}
Note that V's indexes go from V[0][0] to V[0][W-1]. Your for loop will try to read V[0][W].
The same error is repeated in other places. Your end condition in your for loops should be < (strictly less) instead of <= (less or equal than).
I don't think in my code I tried accessing null pointers, or initialising large arrays, someone help please, I dunno where the Runtime Error(SIGSEGV) is coming from. Question to problem can be found at https://www.codechef.com
/MARCH18B/problems/MINEAT
edit:
I think i found out, NathanOliver was right, v1, because of my code, happens to be sometimes empty. Some answers were actually found out of my loop (above n). Thanks alot. I fixed that and I finally got AC, but just 30 points, my code took an additional 0.01 seconds to run. Can anyone help me optimize it, based on Problem statement, Please.
#include <bits/stdc++.h>
using namespace std;
int main()
{
int t; cin>>t; while(t--)
{
int n = 0, h = 0; cin>>n>>h;
vector<int> v; vector<int> v1;
for(int i = 0; i != n; i++){int a; cin>>a; v.push_back(a);}
for(int j = 1; j <= h; j++)
{
int hold = 0;
for(auto k : v)
{
if (j >= k){hold +=1;}
else if (j < k){if(k % j == 0){hold += (k/j);} else{hold += ((k/j)+1);}}
}
if (hold <= h){v1.push_back(j);}
}
cout<<*min_element(v1.begin(),v1.end())<<endl;
}
}
Did you check the min_element function's return value? According to the user input, min_element function returns an iterator to 'last element' which is basically a nullptr. Since you're dereferencing it directly, you get the error.