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.
Related
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.
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'm trying to fix a SIGSEGV error in my program. I am not able to locate the site of error. The program compiles successfully in Xcode but does not provide me the results.
The goal of the program is to check whether the same element occurs in three separate arrays and return the element if it is more than 2 arrays.
#include <iostream>
using namespace std;
int main()
{
int i = 0 ,j = 0,k = 0;
int a[5]={23,30,42,57,90};
int b[6]={21,23,35,57,90,92};
int c[5]={21,23,30,57,90};
while(i< 5 or j< 6 or k< 5)
{
int current_a = 0;
int current_b = 0;
int current_c = 0;
{ if (i<5) {
current_a = a[i];
} else
{
;;
}
if (j<6)
{
current_b = b[j];
} else
{
;;
}
if (k<5)
{
current_c= c[k];
} else
{
;;
}
}
int minvalue = min((current_a,current_b),current_c);
int countoo = 0;
if (minvalue==current_a)
{
countoo += 1;
i++;
}
if (minvalue==current_b)
{
countoo +=1;
j++;
}
if (minvalue==current_c)
{
countoo += 1;
k++;
}
if (countoo >=2)
{
cout<< minvalue;
}
}
}
I am not getting any output for the code.
This is surely not doing what you want
int minvalue = min((current_a,current_b),current_c);
If min() is defined meaningfully (you really should provide an MCVE for a question like this), you want
int minvalue = min(min(current_a,current_b),current_c);
This will result in the minimum of the minimum of (a and b) and c, i.e. the minimum of all three, instead of the minimum of b and c. The comma operator , is important to understand this.
This seems to be a flag/counter to make a note across loop executions or count something
int countoo = 0;
It can however not work if you define the variable inside the loop.
You need to move that line BEFORE the while.
With this line you do not prevent the indexes to leave the size of the arrays,
that is very likely the source for the segfault.
while(i< 5 or j< 6 or k< 5)
In order to prevent segfaults, make sure that ALL indexes stay small enough,
instead of only at least one.
while(i< 5 && j< 6 && k< 5)
(By the way I initially seriously doubted that or can compile. I thought
with a macro for or it could, but I do not see that. It could be a new operator in a recent C++ standard update which I missed...
And it turns out that it is the case. I learned something here.)
This should fix the segfault.
To achieve the goal of the code I think you need to spend some additional effort on the algorithm. I do not see the code being related to the goal.
I was trying to solve solve questions at TopCoder. I was getting weird results on test sections of TopCoder; however, when I submit my code I got AC(stands for accepted). The case was the same on TCHS SRM 47 Level one - 250 pt - Cards Shuffle. I used swap function, my code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
using namespace std;
int main() {
int f, l, t;
string c;
cin>>c;
scanf("%d%d%d", &f, &l, &t);
//while(t--) c=c.substr(f-1, l-f+1)+c.substr(0, f-1)+c.substr(l);
while(t--) for(int i=0, j=f-1; j<=l-1; i++, j++) swap(c[i], c[j]);
cout<<c;
return 0;
}
returns WA(stands for wrong answer) on test section of TC(stands for TopCoder), and AC when submitted on TC. Then I checked the code on ideone, with both substr and swap functions respectively. On first try substr function gave expected result, while swap function unexpected result. However, on second try it was vice versa. I dont know what is going on, whether my code has a bug, or ideone, or TopCoder testing system.
Your Algorithm
Your algorithm using swap is faulty. Let's walk through the steps for one iteration of the while loop. You have:
for ( int i = 0; j = f-1; j <= l-1; ++i, ++i )
swap(c[i], c[j]);
I don't know why you are using f, l, and t. It will be so much easier to read if you use first, last, and times.
for ( int i = 0; j = first-1; j <= last-1; ++i, ++i )
swap(c[i], c[j]);
Let's use the following input:
ABCDEFGHIJ
5 6 1
In the first iteration of the for loop,
i = 0;
j = 4;
after the swap, the new value of c is
EBCDAFGHIJ (A and E are swapped)
In the second iteration of the for loop,
i = 1;
j = 5;
after the swap, the new value of c is
EFCDABGHIJ (B and F are swapped)
The iteration stops here since the value of j becomes 6.
What you needed to end up with is:
EFABCDGHIJ
A Different Algorithm
If you want to minimize the number of strings created, you can use the following strategy.
For the given inputs, create the sub-string "EF" and store it. Then move "ABCDE" to the right by two. Then move "EF" to the start of the string. The following function does that. It changes c in place.
void fun(string& c, int first, int last)
{
// Convert first to a 0-based index for easier manipulation.
--first;
int delta = last-first;
string c1 = c.substr(first, delta);
for ( int i = first-1; i >= 0; --i )
{
c[i+delta] = c[i];
}
for ( int i = 0; i < delta; ++i )
{
c[i] = c1[i];
}
}
I seem to be having some trouble getting this mergesort to run. When I try to run it with g++ the terminal says "Segmentation fault (core dumped)," and I don't know what is causing this to happen (you might be able to tell that I'm still a beginner). Could anybody help out?
#include <iostream>
using namespace std;
void merge (int*, int, int, int);
void mergesort (int* A, int p, int r){
if (p < r){
int q = (p+r)/2;
mergesort (A, p, q);
mergesort (A, q+1, r);
merge ( A, p , q, r);
}
}
void merge (int* A, int p, int q, int r){
int n = q-p+1;
int m = r-q ;
int L [n+1];
int R [m+1];
for (int i=1;i <n+1;i++)
L[i] = A[p+i-1];
for (int j=1; j< m+1; j++)
R[j] = A[q+j];
L[n+1];
R[m+1];
int i= 1;
int j=1;
for (int k = p; k= r + 1; k++){
if (L[i] <= R[j]){
A[k] = L[i];
i+=1;
}
else{
j += 1;
}
}
}
int main() {
int A [15] = {1, 5, 6, 7,3, 4,8,2,3,6};
mergesort (A, 0, 9);
for (int i=0; i <9; i++){
cout << A[i] << endl;
}
return 0;
}
Thanks a lot!
There are three things in your implementation that either don't make sense or are outright wrong:
First these:
L[n+1];
R[m+1];
Neither of these statement have any effect at all, and I've no idea what you're trying to do.
Next, a significant bug:
for (int k = p; k= r + 1; k++){
The conditional clause of this for-loop is the assignment k = r + 1. Since r does not change anywhere within your loop, the only way that expression is false is if r == -1, which it never is. You've just created an infinite-loop on a counter k that will run forever up into the stratosphere, and in the process index, and write, to memory no longer valid in your process. This, as a result, is undefined behavior. I'm fairly sure you wanted this:
for (int k = p; k< (r + 1); k++){
though I can't comment on whether that is a valid limit since I've not dissected your algorithm further. I've not take the time to debug this any further. that I leave to you.
Edit. in your main mergsesort, this is not "wrong" but very susceptible to overflow
int q = (p+r)/2;
Consider this instead:
int q = p + (r-p)/2;
And not least this:
int L [n+1];
int R [m+1];
Uses a variable-length array extension not supported by the standard for C++. You may want to use std::vector<int> L(n+1) etc.. instead.
In your case the segmentation fault is likely being caused when you are trying to read memory in that does not exist for a variable, for example say you have an array called foo of size 10 (so foo[10]) and you this statement foo[11] would cause a segmentation fault.
What you need to do is use debug statements to print out your index variables (i, j, n, m, p and q) and see if any of these are larger than your array sizes
EDIT: Another unrelated issue is that you should not use using namespace std, this line of code can cause scoping issues if you are not careful, just something to keep in mind :)