Reversing an Array Results In SegFault - c++

#include <iostream>
using namespace std;
/*
*
*/
int main() {
int k, in[k],reversea[k],i,m,n;
cin>>k;
for (i=0;i<k;i++){
cin>>in[i];
}
for (m=k-1;m>=0;m--){
for (n=0;n<k;n++){
in[m]=reversea[n];
}
}
for(i=0;i<k;i++){
cout<<reversea[i];
}
return 0;
}
I have no idea why it says segmentation fault even before i start debugging it. I compile another one on calculating the frequency of 1, 5, and 10 in an array of k numbers, and it says the same thing...
Here is the other one:
#include <iostream>
using namespace std;
int main() {
int k,i,m,n,count5,count1,count10;
int input[k];
cin>>k;
for (i=0;i<k;i++){
cin>>input[i];
}//input all the numbers
for(i=0;i<k;i++){
if (input[i]=1){
count1++;
}
if (input[i]=5){
count5++;
}
if (input[i]=10){
count10++;
}
}
cout<<count1<<"\n"<<count5<<"\n"<<count10<<"\n";
return 0;
}
Please help me. Thanks.

On this line
int k, in[k],reversea[k]
How are you supposed to initialize an array with k elements if k isn't initialized? The size of an array must be known at compile time not run time. If k isn't know until run time, use a std::vector
int k;
std::cin >> k;
std::vector<int> in(k);
std::vector<int> reversea(k);

Both your programs have two major faults.
You need to know the size of an array while creating it. In your code, k is still uninitialized and you are using this value as the size of your array. Instead, change it to
int k,i,m,n;
cin >> k;
int in[k];
int reversea[k];
While reversing the array, you should be filling reversea using values from in, and not the other way round. Also, you don't need 2 for loops, just use 1 for loop.
for (m=k-1; m>=0; m--){
reversea[m] = in[k-1-m];
}
In the second program, you again need to get the value of k before creating the array input[k].
You are testing for equality with a = instead of == . Change your code from
if (input[i]=1){
to
if (input[i] == 1) {

Related

Why is there a segmentation fault when I use vector storing vector?

I'm dealing with an algorithm homework which need to be executable on linux(I'm using wsl), and this homework need to store the solution and export to the output file.
To store the solution, I need to open an 2D array of "vectors storing pairs", and at the end, I need to sort the pairs by its first component in the ascending order.
I know that for the first requirement, the running time would be O(N^2)(This is also the standard answer for this dynamic programming problem), and for the second one, I've google C++ STL, and it says that the algorithm used by c++ only needs O(NlogN).
(1)It return 'killed' if I use the new to declare 2D array of vector, for the cases that N=10000, but it works fine if N=1000.
[Edited]
(2) I check the comment, and they suggest that I should write the code using vector to store vector instead of new. However, when I change to using vectors storing vectors, now the program cannot run, keep throwing segmentation fault.
I don't know where is happening. Can anybody help?
problem description:
https://drive.google.com/file/d/1m8ISIGlVGXH3oeyechLbBA1QQVSmsw-q/view?usp=sharing
file: https://drive.google.com/file/d/1Ci8MXUsX65oVOxKCD1u3YcWiXsKNYToc/view?usp=sharing
Note:
The .o files are alredy make, finish editing, you need to 'make', and run
./bin/mps [inputfile] [outputfile]
I've modified some code, but it can only run with case N=12, 1000; not for larger N.
chord.h:
#include <vector>
#include <utility>
#include <algorithm>
using namespace std;
class Chord {
public:
Chord(int);
~Chord();
void setEndPoint(int, int);
int getMaximumChords();
void print();
int size;
int* data; //stores the endpoints of the chord
// vector<pair<int,int>>** sol;
//I recently use this(1), works for N=1000, but killed if N larger
vector< vector< vector<pair<int, int>> >>sol;
//suggest to change to this(2), not working even for N=12,
//return segmentation fault
int getEndPoint(int);
};
chord.cpp:
#include "chord.h"
#include <iostream>
Chord::Chord(int tmp){ //initialize all elements 0
size = tmp;
data = new int [size];
};
Chord::~Chord(){
delete[] data;
}
void Chord::setEndPoint(int a, int b){
data[a] = b;
data[b] = a;
return;
}
void Chord::print(){
for(int i=0;i<size; i++){
cout << data[i] << endl;
}
return;
}
int Chord::getEndPoint(int a){
return data[a];
}
int Chord::getMaximumChords(){
for(int j=1; j<size; j++){
for(int i=j-1; i>=0; i--){
int k = getEndPoint(j);
if(k==i){ //case 1: ij is the chord
sol[i][j] = sol[i+1][j-1]; //make a copy
sol[i][j].reserve(1);
sol[i][j].push_back(make_pair(i,j));
}else if(k<i || k>j){ //case 2: k outside interval[i,j]
sol[i][j] = sol[i][j-1];
}else{ //case 3: k inside interval[i,j]
if (sol[i][j-1].size() > sol[i][k-1].size() + sol[k+1][j-1].size() + 1){
sol[i][j] = sol[i][j-1];
}else{
sol[i][j] = sol[i][k-1];
sol[i][j].reserve(sol[k+1][j-1].size()+1);
sol[i][j].push_back(make_pair(k,j));
sol[i][j].insert(sol[i][j].end(),sol[k+1][j-1].begin(), sol[k+1][j-1].end());
}
}
}
}
sort(sol[0][size-1].begin(), sol[0][size-1].end());
return sol[0][size-1].size();
}
main.cpp
#include <iostream>
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include "chord.h"
using namespace std;
int main(int argc, char* argv[]){
if (argc < 3){
printf("Please enter output file name!");
return 0;
}
//import input
fstream fi(argv[1]);
fstream fo;
fo.open(argv[2], ios::out);
int N=0, a=0, b=0;
char buffer[200];
fi >> N;
Chord chord(N);
while(fi>> a >>b){
chord.setEndPoint(a,b);
}
//chord.print();
int ans= chord.getMaximumChords();
//export output
fo << ans <<endl;
for(int i=0; i<chord.sol[0][chord.size-1].size(); i++){
fo << chord.sol[0][chord.size-1][i].first << " " << chord.sol[0][chord.size-1][i].second << endl;
}
fi.close();
fo.close();
return 0;
}
By default, std::vector is constructed with 0 size, and I see that you don't ever resize the vector, but you access its elements by index [i][j]. You have to resize first two (or maybe three) dimensions of 3-dimensional vector sol to fit necessary size, do following resize inside constructor:
Chord::Chord(int tmp){ //initialize all elements 0
size = tmp;
data = new int [size];
sol.resize(size, vector< vector<pair<int, int>> >(size));
};
After this resize change in constructor your program doesn't crash on 10000 input, at least on my Windows laptop.
Also maybe you need to resize two dimensions to bigger than size, you should know better. Also 3rd dimension might be needed to resize too, if you need this by algorithm, up to you. If you need to resize 3rd dimension, then do following (but if I understand your algorithm correctly you don't need this change, resizing 3rd dimension, you need it to be of size 0):
sol.resize(size1, vector< vector<pair<int, int>> >(size2, vector<pair<int, int>>(size3)));
(here size1/size2/size3 are three sizes of three dimensions, so that your vector gets 3-dimensional shape (size1, size2, size3), decide what these 3 sizes should be at your algorithm start, I think they should be (size, size, 0))

Why this code doesn't allow me to receive the whole array?

#include <bits/stdc++.h>
using namespace std;
string bin(int n){
string x="";
while(n!=0)
{
int z=n%2;
x+=to_string(z);
n%=2;
}
return x;
}
int main(){
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int a[n];
for(int i=0;i<n;i++)
{
cin>>a[i];
string x=bin(a[i]);
int u=x.size();
int cnt=0;
for(int g=0;g<u;g++)
{
if(x[g]=='1')
++cnt;
}
cout<<cnt<<' ';
}
cout<<'\n';
}
}
This code is given several test cases and each test case will have an array of n integers, for each element in the array I should count the number of ones in the binary representation of it. I wrote a function that expects an integer and returns a string containing the binary representation of it. But I wonder why my code does not end, and not allowing me to receive other numbers in array.
For instance, there's one test case and and only array of 2 integers if I inputted 1 and wait for ever to enter the second number, what's happening?
This is your bin function reduced to the bare minimum:
string bin(int n){
while(n!=0)
{
n%=2;
}
return {};
}
If n is even you will set it to 0 on the first iteration, otherwise you set it to 1 and never change it afterwards (1%2==1). Hence you have a endless loop. I won't spoil you the "fun" of completing the exercise, so I will just point you to using a debugger. If you step trough your code line by line you could have observed how n never changes and why the loop wont stop.
PS: (spoiler-alert) you might want to take a look at std::bitset (end of spoiler)

Why does this code have a segmentation fault?

I find that that while running this code it says:
Thread1:EXC_BAD_ACCESS(code=1,address=0x7fff3010efcc)
Code:
#include <iostream>
using namespace std;
int main()
{
int d[20],n,k,j,i,a[100000000],count=0;
//long long int i,a[100000000];
cin>>n>>k;
for(i=0;i<k;i++)
{
cin>>d[i];
}
for(i=0;i<n;i++)
{
a[i]=i;
}
for(i=0;i<n;i++)
{
for(j=0;j<k;j++)
{
if(a[i]%d[j]==0)
{
a[i]=0;
}
}
}
for(i=0;i<n;i++)
{
if(a[i]!=0)
{
count++;
}
}
cout<<count;
}
The stack has overflowed. There is no place for int a[100000000] as its size exceeds the default stack size (1MB on Windows)
If we don't know the values of n and k, we can't respond appropriately to your question.
By example, if you give the value 21 to k, you write (cin >> d[i]) d in position 20; this can cause the segmentation fault.
Suggestions:
1) run your program in a debugger
2) check the values for n and k
3) and use std::vector instead old C-style arrays and at() instead operator[] (by example: cin >> d.at(i), a.at(i) = i, etc. instead cin >> d[i], a[i] = i, etc.) because at() perform a bound checking.

Variables being affected by 'bad' instructions

Below is my code, for solving problem 7 of PE ("find the 10001th prime"):
#include <iostream>
using namespace std;
bool isPrime(int n, int primes[], int l){
int i=0;
for (int i=0; i < l; i++){
if (primes[i] != 0 && n%primes[i] == 0){
return false;
}
}
return true;
}
int main()
{
int k=3;
int primes[10001] = {0};
primes[0]=2;
const int l=sizeof(primes)/sizeof(primes[0]);
int N=0;
while (N < l){
if(isPrime(k, primes, l)==true){
primes[++N]=k;
}
k+=2;
}
cout << primes[l-1] << endl;
return 0;
}
This code solves the problem, but there is a mistake in it: on the final iteration of the while loop, the instruction is to set primes[10001]=k;, which attempts to change a value of an element of an array that doesn't exist. If I don't declare it to be constant, and (as a means of troubleshooting) replace l by 10001 in the while loop, the value of l becomes equal to the 10002th prime at the end of the loop.
Here is the main function part of this happening:
int main()
{
int k=3;
int primes[10001] = {0};
primes[0]=2;
int l=sizeof(primes)/sizeof(primes[0]);
int N=0;
while (N < l){
if(isPrime(k, primes, 10001)==true){
primes[++N]=k;
}
k+=2;
}
cout << l << endl;
return 0;
}
My question is, why does this happen? I do know that a simple fix is to stop the loop at l-1 (or better, initialize with N=1 instead and increment N after), but I'm more interested in how this code can affect a variable that isn't being explicitly (directly?) involved in the bad part of the code.
Thank you!
The [] Operator does no bounds checking. some_array[102], will simple go 102 * sizeof(type) if thats outside your array, thats outside your array. C++ won't care.
These are some of the nastiest bugs that can generated if you are lucky you program will crash, sometimes you can just end up changing somebody else's variable.
Which is why I harp on at work about using std::array and std::vector alot because they come with .at(i) functions which have bounds checking.

array concatenation of two different arrays

im doing simple genetic algorithm uniform crossover operation . for that im using two arrays as parent and mother.i want concatenate the childs for getting the offsprings(childs).
i have problem in adding the arrays .any help plssss.i did it ubuntu
#include<iostream>
#include <fstream>
#include <algorithm>
#include<vector>
using namespace std;
int main()
{
int P[ ]={3,7,6,5,2,4,1,8};
int N[ ]={8,6,7,2,5,3,4,1};
int r= (sizeof(P)/sizeof(*P)) ;
int s= (sizeof(N)/sizeof(*N));
int val=r/2 ;
int t1[val],t2[val],t3[val],t4[val],n=0,p=0;
for(int m=0;m< val;m++)
{
t1[n]=P[m];
t2[n]=N[m];
n++;
}
for(int x=val;x< r;x++)
{
t3[p]=P[x];
t4[p]=N[x];
n++;
}
int* child=new int [val+val];
copy(t1,t1+val,child);
copy(t3,t3+val,child+val);
cout << child;
}
return 0;
}
This part is wrong:
int t1[val], t2[val], t3[val], t4[val]
You can only use constant values to declare the size of arrays.
You can either use a std::vector or dynamically allocate memory for the t-arrays.
std::vector<int> t1(val);
std::vector<int> t2(val);
for(int m = 0; m < val; m++)
{
t1[n] = P[m];
t2[n] = N[m];
n++;
}
There seem to be multiple errors in your code.
Variable length arrays are at present not supported in C++.
int val=r/2 ;
int t1[val]; // Not OK
In the second for loop I guess you meant p++ instead of n++;
Instead of manually doing all the memory allocation - deallocation, you should use std::vectors
cout << child; // This outputs the address of the pointer, not the entire array.