Why does this code produce a segfault? - c++

Code:
#include <iostream>
using namespace std;
void mix(int *a, int *b, int *c, int m, int n)
{
int i, j = 0;
for(i = 0; i < m; i++)
{
if(a[i] % 2 == 0)
{
c[j] = a[i];
j++;
}
}
for(i = m - 1; i >= 0; i++)
{
if(a[i] % 2 == 1)
{
c[j] = a[i];
j++;
}
}
for(i = 0; i < n; i++)
{
if(b[i] % 2 == 0)
{
c[j] = b[i];
j++;
}
}
for(i = n - 1; i >= 0; i++)
{
if(b[i] % 2 == 1)
{
c[j] = b[i];
j++;
}
}
cout << j << ' ';
}
int main()
{
int a[10], b[10], c[20], m, n;
cout << "m: ";
cin >> m;
cout << "\nn: ";
cin >> n;
int i;
for(i = 0; i < m; i++)
{
cin >> a[i];
}
for(i = 0; i < n; i++)
{
cin >> b[i];
}
mix(a, b, c, m, n);
for(i = 0; i < (m+n); i++)
{
cout << c[i];
}
return 0;
}
I've checked and rechecked the sizes of my arrays and I cannot figure out why the code produces a segfault in the mix(...) function. Could it be a problem of using -O2 optimisation? Furthermore, I've made sure the indices match up. I think the problem is with c[j] = a[i], but I do not understand why that would be causing this segmentation fault.

for these two loop you were doing i++ instead of i--
for(i = m - 1; i >= 0; i--)
{
if(a[i] % 2 == 1)
{
c[j] = a[i];
j++;
}
}
for(i = n - 1; i >= 0; i--)
{
if(b[i] % 2 == 1)
{
c[j] = b[i];
j++;
}
}

Related

How to display this pyramid of numbers?

I have this task:
A user inputs a number N and you have to output this pyramid:
0
101
21012
.......
N.21012.N
For N=5 it will be :
0
101
21012
3210123
432101234
54321012345
I managed to only get it working for N<10 with this code:
int n;
cin >> n;
for (int i = 0; i < n + 1; i++) {
for (int j = 0; j < n - i; j++)
cout << " ";
int dir = -1;
for (int k = i; k <= i; k += dir) {
cout << k;
if (k == 0)
dir = 1;
}
cout << endl;
}
For N=10 it will look like this :
0
101
21012
3210123
432101234
54321012345
6543210123456
765432101234567
87654321012345678
9876543210123456789
10987654321012345678910
After the answers I settled on this :
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
int main()
{
int n, spaces;
string number;
cin >> n;
if (n < 10)
spaces = n;
else
{
spaces = 9;
int pwr = 0, k = n;
while (k > 9)
{
pwr++;
k /= 10;
}
for (int i = 1; i < pwr; i++)
{
spaces += pow(10, i) * 9 * (i + 1);
}
spaces += (n - pow(10, pwr) + 1) * (pwr + 1);
}
// cout << spaces << endl;
for (int i = 0; i < n + 1; i++)
{
for (int j = i; j > -1; j--)
number += to_string(j);
int len = number.length() - 1;
for (int j = 0; j < spaces - len; j++)
cout << " ";
for (int j = 1; j <= i; j++)
number += to_string(j);
cout << number << endl;
number.clear();
}
cout << endl;
return 0;
}
int padding(int n) {
constexpr auto singleDigitNumbersCount = 9;
constexpr auto doubleDigitNumbersCount = 90; // from 10 to 99
if (n < 10) return n;
if (n < 100) return 2*n - singleDigitNumbersCount;
return 3*n - doubleDigitNumbersCount - 2*singleDigitNumbersCount;
}
int main() {
int n;
cin >> n;
for (int i = 0; i < n + 1; i++) {
std::cout << std::string(padding(n) - padding(i), ' ');
for (int k = i; k >= 0; k--) {
cout << k;
}
for (int k = 1; k <= i; k++) {
cout << k;
}
cout << '\n';
}
return 0;
}
https://godbolt.org/z/EEaeWEvf4
I made this a bit ago Compiler Explorer
Not sure if that'd help 🤔
Here is the working code:
#include <string>
#include <iostream>
using namespace std;
#define MAX_SPACE 50
int main()
{
int n;
cin >> n;
string output = "";
for (int i = 0; i < n + 1; i++)
{
for (int k = i; k >= 0; k--) {
output += to_string(k);
}
for (int k = 1; k <= i; k++) {
output += to_string(k);
}
for (uint8_t i = 0, max = MAX_SPACE - output.length() / 2.00; i < max; i++) // Print max spaces minus the integer length divided by 2
{
cout << " ";
}
cout << output << endl; // Print number
output = "";
}
return 0;
}

is there other way to fill in array in C++ without vector

So I have array A and B, two of them contain random numbers and I need to write in the C array initially even numbers of A and B and then odd. I have made this wtih vector but I wonder if there is other way to do it like in Javascript there are methods like .unshift(), .push() etc
#include<iostream>
#include<vector>
using namespace std;
int main() {
const int n = 4;
int A[n];
int B[n];
vector<int>C;
for (int i = 0; i < n; i++)
{
A[i] = rand() % 10;
cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
B[i] = rand() % 30;
cout << B[i] << " ";
}
for (int i = 0; i < n; i += 1)
{
if (A[i] % 2 == 0)
{
C.push_back(A[i]);
}
if (B[i] % 2 == 0)
{
C.push_back(B[i]);
}
}
for (int i = 0; i < n; i++)
{
if (A[i] % 2 != 0)
{
C.push_back(A[i]);
}
if (B[i] % 2 != 0)
{
C.push_back(B[i]);
}
}
cout << endl;
for (int i = 0; i < C.size(); i++)
cout << C[i] << " ";
}
I would suggest interleaving A and B initially:
for (int i = 0; i < n; i += 1)
{
C.push_back(A[i]);
C.push_back(B[i]);
}
And then partitioning C into even and odd elements:
std::stable_partition(C.begin(), C.end(), [](int i) { return i % 2 == 0; });
vector::push_back is the simplest way to have a collection that grows as you add things to the end.
Since you have fixed size for A and B, you could make them primitive arrays instead, which is what you have done. But for C you don't know how long it will be, so a collection that has a changeable size is appropriate.
You can use std::array, if you know the size you need in compile time. You can then add using an iterator.
#include<vector>
using namespace std;
int main() {
const int n = 4;
int A[n];
int B[n];
std::array<int, n+n>C; // <-- here
auto C_it = C.begin(); // <-- here
for (int i = 0; i < n; i++)
{
A[i] = rand() % 10;
cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
B[i] = rand() % 30;
cout << B[i] << " ";
}
for (int i = 0; i < n; i += 1)
{
if (A[i] % 2 == 0)
{
*C_it++ = A[i]; // <-- here
}
if (B[i] % 2 == 0)
{
*C_it++ = B[i];
}
}
for (int i = 0; i < n; i++)
{
if (A[i] % 2 != 0)
{
*C_it++ = A[i];
}
if (B[i] % 2 != 0)
{
*C_it++ = B[i];
}
}
cout << endl;
for (int i = 0; i < C.size(); i++)
cout << C[i] << " ";
}
Alternatively if you want to be more safe you can hold the next unwritten index and access elements with C.at(last++) = A[i], which checks for out-of-bounds and throws an exception instead of UB.
well you don't to change much.
first of declare C array as int C[n+n]; and declare a variable for incrementing through c array as int j=0;
and in if statements of loops do this C[j]=A[i]; j++; for first if and C[j]=B[i]; j++; for the second if statements
int main() {
const int n = 4;
int A[n];
int B[n];
int C[n+n];
int j=0;
for (int i = 0; i < n; i++)
{
A[i] = rand() % 10;
cout << A[i] << " ";
}
cout << endl;
for (int i = 0; i < n; i++)
{
B[i] = rand() % 30;
cout << B[i] << " ";
}
for (int i = 0; i < n; i += 1)
{
if (A[i] % 2 == 0)
{
C[j]=A[i];
j++;
}
if(B[i]%2==0){
C[j]=B[i];
j++;
}
}
for (int i = 0; i < n; i++)
{
if (A[i] % 2 != 0)
{
C[j]=A[i];
j++;
}
if (B[i] % 2 != 0)
{
C[j]=B[i];
j++;
}
}
j=0;
cout << endl;
for (int i = 0; i < C[].lenght(); i++)
cout << C[i] << " ";
}

Check if 2 arrays are same or not (C++)

I want to compare two int arrays and find if they are the same and if they are not i want to find the min and the max number that exist in one but not in the other. I use this code in c++ but seems to run into a segmentation fault 11. I would be grateful if someone points out the mistake to me.I would like to see better solutions if there are any.
+ I did the mergesort for time limit of 1 second.
#include <iostream>
using namespace std;
void merge(int *a,int s,int e)
{
int mid = (s+e)/2;
int i = s;
int j = mid+1;
int k = s;
int temp[100];
while(i<=mid && j<=e)
{
if(a[i] < a[j])
{
temp[k++] = a[i++];
}
else
{
temp[k++] = a[j++];
}
}
while(i<=mid)
{
temp[k++] = a[i++];
}
while(j<=e)
{
temp[k++] = a[j++];
}
for(int i=s;i<=e;i++)
{
a[i] = temp[i];
}
}
void mergeSort(int a[],int s,int e)
{
if(s>=e)
{
return;
}
int mid = (s+e)/2;
mergeSort(a,s,mid);
mergeSort(a,mid+1,e);
merge(a,s,e);
}
int min_array (int array1[],int n1)
{
int min = array1[0];
for(int i=1;i<n1;i++)
if(array1[i] < min)
min = array1[i];
return min;
}
int max_array (int array2[],int n2)
{
int max = array2[0];
for(int i=1;i<n2;i++)
if(array2[i] > max)
max = array2[i];
return max;
}
void check_same(int a[], int b[], int n)
{
bool check = true;
int check1 = 2, check2 = 2, counter1 = 0, counter2 = 0, i, j;
int pos1[n], pos2[n];
mergeSort(a, 0, n);
mergeSort(b, 0, n);
for(i=0; i<n; i++)
{
if (a[i] != b[i])
check = false;
for(j=0; j<n; j++)
{
if (a[i] != b[j])
check1 = 0;
else if (a[i] == b[j])
check1 = 1;
else if (a[j] != b[i])
check2 = 0;
else if (a[j] == b[i])
check2 = 1;
if (check1 == 1 && check2 == 1)
break;
}
if (check1 == 0)
pos1[counter1++] = i;
else if (check2 == 0)
pos2[counter2++] = i;
}
int differents[counter1 + counter2];
if (counter1 < counter2)
{
for (i=0; i<counter1; i++)
differents[i] = a[pos1[i]];
for (i=counter1; i<counter2; i++)
differents[i] = b[pos2[counter2 - i]];
}
else
{
for (i=0; i<counter2; i++)
differents[i] = b[pos2[i]];
for (i=counter2; i<counter1; i++)
differents[i] = a[pos1[counter1 - i]];
}
if (check)
cout << "yes\n";
else if (check == false)
cout << "no " << min_array(differents, counter1+counter2)<< " " << max_array(differents, counter1+counter2) << endl;
}
int main()
{
int N, i;
cin >> N;
int A[50000], B[50000];
for (i=0;i<N;i++)
cin >> A[i];
for (i=0;i<N;i++)
cin >> B[i];
check_same(A, B, N);
}
Your code is not standard C++, the line int pos1[n], pos2[n]; in check_same is invalid because n is not a compile time constant - VLAs are only allowed in C.
You could make use of the standard library for all of that:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
void check_same(int a[], int b[], int n) {
std::sort(a, a + n);
std::sort(b, b + n);
if(std::equal(a, a + n, b)) {
std::cout << "yes\n";
} else {
std::vector<int> elements_not_in_both;
std::set_symmetric_difference(a, a + n,
b, b + n,
std::back_inserter(elements_not_in_both));
auto [min, max] = std::minmax_element(elements_not_in_both.cbegin(),
elements_not_in_both.cend());
std::cout << "no " << *min << " " << *max << '\n';
}
}
int main()
{
int N;
std::cin >> N;
int A[50000], B[50000];
for (int i=0; i<N; i++)
std::cin >> A[i];
for (int i=0; i<N; i++)
std::cin >> B[i];
check_same(A, B, N);
}
Live demo.
An even better solution is to not use C-style arrays either, then you don't allocate way too much stack space for small input arrays and you can't have too little space when someone decides to run this on more than 50000 elements:
#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>
void check_same(std::vector<int>& a, std::vector<int>& b) {
std::sort(a.begin(), a.end());
std::sort(b.begin(), b.end());
if(a == b) {
std::cout << "yes\n";
} else {
std::vector<int> elements_not_in_both;
std::set_symmetric_difference(a.cbegin(), a.cend(),
b.cbegin(), b.cend(),
std::back_inserter(elements_not_in_both));
auto [min, max] = std::minmax_element(elements_not_in_both.cbegin(),
elements_not_in_both.cend());
std::cout << "no " << *min << " " << *max << '\n';
}
}
int main()
{
int N;
std::cin >> N;
std::vector<int> a, b;
a.reserve(N);
b.reserve(N);
std::copy_n(std::istream_iterator<int>(std::cin), N, std::back_inserter(a));
std::copy_n(std::istream_iterator<int>(std::cin), N, std::back_inserter(b));
check_same(a, b);
}
Please check out for these points for solving segmentation fault issue:
merge function
1) Is this statement int k = s; correct? Shouldn't it be int k = 0;
2) Is this allocation int temp[100]; OK? Or Should it be int temp[e - s + 1];
3) Is this statement a[i] = temp[i]; correct? Shouldn't it be a[i] = temp[i - s];
4) Do you need to have base condition s < e or something? i.e. Handling the case when s == e.
check_same function
1) Is this call mergeSort(a, 0, n); correct? Shouldn't it be mergeSort(a, 0, n - 1);
As far as better approach is concerned, it can be solved in O(n) using hashing.
#include <iostream>
#include <vector>
#include <unordered_set>
using namespace std;
void check_same(int a[], int b[], int n) {
int minNotInA, maxNotInA, minNotInB, maxNotInB;
bool elementMissingInA = false, elementMissingInB = false;
{
unordered_set<int> elementsInB;
for (int i = 0; i < n; i++) {
elementsInB.insert(b[i]);
}
for (int i = 0; i < n; i++) {
if (elementsInB.find(a[i]) == elementsInB.end()) {
if (!elementMissingInA) {
elementMissingInA = true;
minNotInB = maxNotInB = a[i];
} else {
if (minNotInB > a[i]) {
minNotInB = a[i];
} else if (maxNotInB < a[i]) {
maxNotInB = a[i];
}
}
}
}
}
if (elementMissingInA) {
unordered_set<int> elementsInA;
for (int i = 0; i < n; i++) {
elementsInA.insert(a[i]);
}
for (int i = 0; i < n; i++) {
if (elementsInA.find(b[i]) == elementsInA.end()) {
if (!elementMissingInB) {
elementMissingInB = true;
minNotInA = maxNotInA = b[i];
} else {
if (minNotInA > b[i]) {
minNotInA = b[i];
} else if (maxNotInA < b[i]) {
maxNotInA = b[i];
}
}
}
}
}
if (elementMissingInA and elementMissingInB) {
cout << "no " << min(minNotInA, minNotInB) << " " << max(maxNotInA, maxNotInB) << "\n";
} else {
cout << "yes\n";
}
}
int main()
{
int N;
std::cin >> N;
int A[50000], B[50000];
for (int i=0; i<N; i++)
std::cin >> A[i];
for (int i=0; i<N; i++)
std::cin >> B[i];
check_same(A, B, N);
return 0;
}
Thank all of you for your interest and your help.
Because i am not used to those kinds of libraries you use and i dont want to study them at the moment(i am just in the first semester of my ece class) i corrected my code(both improved it and fixed the segmentation fault 11)
You can take a look right here.
#include <iostream>
using namespace std;
void merge(int *a, int s, int e)
{
int mid = (s + e) / 2;
int i = s;
int j = mid + 1;
int k = s;
int temp[50000];
while (i <= mid && j <= e)
{
if (a[i] < a[j])
{
temp[k++] = a[i++];
}
else
{
temp[k++] = a[j++];
}
}
while (i <= mid)
{
temp[k++] = a[i++];
}
while (j <= e)
{
temp[k++] = a[j++];
}
for (int i = s; i <= e; i++)
{
a[i] = temp[i];
}
}
void mergeSort(int a[], int s, int e)
{
if (s >= e)
{
return;
}
int mid = (s + e) / 2;
mergeSort(a, s, mid);
mergeSort(a, mid + 1, e);
merge(a, s, e);
}
int min_array(int array1[], int n1)
{
int min = array1[0];
for (int i = 1; i<n1; i++)
if (array1[i] < min)
min = array1[i];
return min;
}
int max_array(int array2[], int n2)
{
int max = array2[0];
for (int i = 1; i<n2; i++)
if (array2[i] > max)
max = array2[i];
return max;
}
void check_same(int a[], int b[], int n)
{
int differents[50000];
int counter1 = 0, counter2 = 0;
int i = 0, j = 0;
while (i < n && j < n)
{
if (a[i] < b[j])
{
differents[counter1++ + counter2] = a[i];
i++;
}
else if (b[j] < a[i])
{
differents[counter2++ + counter1] = b[j];
j++;
}
else
{
i++;
j++;
}
}
if (counter1 == 0 && counter2 == 0)
cout << "yes\n";
else
cout << "no " << min_array(differents, counter1 + counter2) << " " << max_array(differents, counter1 + counter2) << endl;
}
int main()
{
int A[50000], B[50000];
int N, i;
cin >> N;
for (i = 0; i<N; i++)
cin >> A[i];
for (i = 0; i<N; i++)
cin >> B[i];
mergeSort(A, 0, N-1);
mergeSort(B, 0, N-1);
check_same(A, B, N);
return 0;
}

HackerRank says ~no response on stdout~. C++

I wrote this solution for the absolute permutation problem on HackerRank. It works fine on dev-C++ but doesn't work on Hackerrank. I've found that the code produces output when I remove the abs_perm(). What's the problem here?
#include <iostream>
using namespace std;
int arr[100000];
int check(int n, int k)
{
if ( (2*k == n) || (k == 0) || (n - 4*k == 0) )
return 1;
else if (k < n/2)
return check(n - 4*k, k);
else
return 0;
}
void swap(int &a, int &b)
{
int c = b;
b = a;
a = c;
}
void ini(int n)
{
for (int i = 0; i < n; i++)
{
arr[i] = i+1;
}
}
void abs_perm(int n, int k)
{
for (int i = 0; i < k; i++)
{
swap(arr[i], arr[k+i]);
}
if (2*k == n)
return;
for (int i = n - 1; i > n - k - 1; i--)
{
swap(arr[i], arr[i-k]);
}
if (n - 4*k == 0)
return;
abs_perm(n - 4*k, k);
}
int main()
{
int T;
cin >> T;
int N[T], K[T];
for (int i = 0; i < T; i++)
{
cin >> N[i] >> K[i];
}
for (int i = 0; i < T; i++)
{
cout << N[i] << " " << K[i] << "\n";
}
for (int i = 0; i < T; i++)
{
if ( !check(N[i], K[i]) )
cout << "-1\n";
else
{
ini(N[i]);
abs_perm(N[i], K[i]);
for (int j = 0; j < N[i]; j++)
{
cout << arr[j] << " ";
}
cout << "\n";
}
}
return 0;
}
Array is a structure to use when you know at compile time the dimension of your structure. What you wrote at the begin in abs_perm() is not correct for standard compilers (in fact you don't know the dimension of your array). You can use a std::vector or a std::list which allocate memory dynamically or (bad solution) you can allocate an array with dimension that certainly contains all elements you will put inside.

Translating a simple for loop into a while loop?

How can I write this same code with the while loop instead of the for loop?
int n;
cin >> n;
for (int i = 1; i <= n; i++) {
for (int j = n; j >= i; j--) {
cout << j;
}
cout << endl;
}
This is my attempt, but it does not achieve the same affect. I'm not sure why.
int n;
cin >> n;
int i = 1;
int j = n;
while (i <= n) {
while (j >= i) {
cout << j;
j--;
}
i++;
cout << endl;
}
You have to reset j before the while(j >= i) loop.
while (i <= n) {
j = n; //<<<<<<<< Reset j to the starting value
while (j >= i) {
cout << j;
j--;
}
i++;
cout << endl;
}