For loop - more in output than needed - c++

Well all I had to do was:
user has to enter 20 numbers.
and I should find from array numbers lower than the last number user entered ( 20 numbers )
Example :
User enters:
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,4
Output should be:
1,2,3
according to me, my output is correct. But after 1,2,3 alot of 0 come in.
#include <iostream>
using namespace std;
int i,skaitlis,sk2,x;
int masivs[19];
int main() {
for ( i=0; i<=19; i++ )
{
cin >> masivs[i];
skaitlis = masivs[19];
}
for (i=0;i < sizeof masivs; i++){
if ( masivs[i]<skaitlis){
cout << masivs[i] <<endl;
}
}
}

The problem is here:
for (i=0;i < sizeof masivs; i++){
The sizeof operator returns the size of the array in bytes, not in number of elements. On normal modern systems the size of an int is four bytes, meaning sizeof masivs will give you 4*19.
That will lead the loop going massively out of bounds and give you undefined behavior.
Not to mention the other out of bounds you have in the previous loop.
Also, taking about the first loop, why have the assignment to skaitlis inside the loop? After you fix the out-of-bounds indexing, it will just assign zero (because masivs is a global variable and therefore initialized to all zeroes) except in the last iteration. You can move that assignment to be outside the loop.

Related

the largest element in the array outputs as -858993460 [C++]

im trying to let the user input a number for each person. the console then outputs the maximum value in the array. everything works fine but the max always outputs as -858993460. i tried multiple combinations but i cant seem to figure it out
im new to arrays so any help would be appreciated as well as an feedback on how to improve my code
#include <iostream>
int main()
{
int people[10];
int max = people[0];
std::cout << "please enter number of pancakes eaten by each person.\n";
//lets the user input values for each element
for (int i = 0; i < 10; ++i) {
std::cin >> people[i];
}
//outputs all the elements of the array
for (int i = 0; i < 10; ++i) {
std::cout << people[i] << " ";
}
//finds the largest element in the array
for (int i = 0; i > 10; ++i) {
if (people[i] > max) {
max = people[i];
}
}
std::cout << "\nmax: " << max;
return 0;
}
also i keep getting a warning saying: ill-defined for-loop. loop body not executed. i tried looking this warning up but the warning seems very broad and i couldnt find anything that helped
int people[10];
This declares an array of ten int values. None of the values are explicitly initialized. This is how plain values that get declared in automatic scope work in C++, they are not initialized to any values. It is the code's responsibility to initialize them.
int max = people[0];
This sets the value of max to the first value of the array. Which has not been initialized to any value. This is undefined behavior. From this point on the program's behavior is undefined.
Furthermore, even if peoples values were initialized this will still be broken. The intent of the program is clear: read values into the people array, and then find their maximum value.
However, at this point, nothing has been read from anywhere.
The attempted goal here is to set max, initially, to the first value in the array, the first read value.
But in order for this to make sense, max should be set after the values in the array get read from input, and not before. This should be done after all the values are read in, and not before.
in the line int max = people[0] you are dereferencing the first element of the array. But dereferencing to what? at that point in the program you have not initialised any of the 10 elements in the people array. So taking the value at people[0] at that point in the program and copying it into another int for later comparison is undefined behaviour. Best solution is to simply move int max = people[0] to after you take the user input, and for the comparison loop start with i = 1, because max is already equivalent to the first inputted value.

c++ runtime error when 2d array assigning another array value

#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;

How to do array

I am trying to learn how to code array.. (i am still a beginner in programming just starting to learn last year) i don't know what's wrong in my code.. the problem is to take 5 integer inputs from user and store them in an array. Again ask user to give a number. Now, tell user whether that number is present in array or not. but my code doesn't recognize my else. Even if i put a number that isn't present in my array it still says "It is present".
int main(){
int num[4];
int i;
int comp;
cout<<"Please input 5 numbers: "<<endl;
for (i=0;i<=4;i++)
{
cin>>num[i];
}
cout<<"Now please input another number to compare: ";
cin>>comp;
if (num[i]=comp){
cout<<"The number you inputted is present in the array";
}
else {
cout<<"It is not present in the array";
}
}
the problem is to take 5 integer inputs from user and store them in an array.
Let's start declaring an array that can hold up to 5 integers.
int numbers[5] = {};
// ^^^ This should be the size of the array, not the maximum index
Since C++11, you can use a proper standard container
std::array<int, 5> numbers{};
Note that in both snippet I initialized those arrays.
Now, the loop that reads all the elements of the array can be written as
for (int i = 0; i < 5; ++i) {
// ^
}
Or use a ranged for
for (auto & number : numbers)
{ // ^^^^^^^^ Loops through the array using `number` as a reference to each element
std::cin >> number;
if (!std::cin) {
std::cerr << "An error occurred while reading.\n";
break;
}
}
The posted loop also goes from 0 to 4 (included), but the array declared in that snippet only has 4 elements, so that it is accessed out of bounds and the program has undefined behaviour.
Another problem, is that the program doesn't check
whether that number is present in array or not
It does only one "check", instead of a loop:
if ( num[i] = comp) {
num[i] = comp is an assignment, not a comparison (you should adequately rise your compiler warning level) and an assignment to an element outside the array (i has value 5, now). It's the result of this assignment, comp, that is used as a condition, which means that the branch is executed whenever comp is not 0.
Or, at least, this is the most likely outcome, given that that assignment is UB too and the compiler could genereate whatever code it decides or your program could seg-fault due to that access out of bounds.
#include "stdafx.h"
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
int num[4];
int i;
int comp;
int coo;
int flg=0;
std::cout<<"Please input four numbers: "<<"\n";
for (i=0;i<=3;i++)
{
std::cin>>num[i];
}
std::cout<<"Now please input another number to compare: ";
std::cin>>comp;
for (i=0;i<=3;i++)
{
if (num[i]==comp){
flg = 1;
break;
}
}
if (flg) {
printf("The number you inputted is present in the array.\n","%s");
} else {
printf("It is not present in the array\n", "%s");
}
std::cin>>coo;
return 0;
}
Basically, you ommitted to loop through all the array members when comparing the array with the number to be compared and I just added the loop in so that it looped through all array members and compared it with the input number.

Sieve of Eratosthenes prime numbers up to a million c++

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.

Any integer input except one with "6" as the right-most digit works, but any number like ...6 leads to segmentation fault, why?

My C++ program named "coinChange.cpp" reports the number of notes of different figures for changing a given integer amount. The code is
#include<iostream>
#include<string>
#include<sstream>
using namespace std;
int main()
{
cout<<"please enter the amount: ";
int amount;
cin>>amount;
int totalNoOfCoins=0;
int coins[]= {100,50,20,10,5,1};
int noOfCoins[sizeof(coins)]= {0};
int counter=0;
while(amount>0)
{
if(amount>coins[counter])
{
noOfCoins[counter]=amount/coins[counter];
amount-=noOfCoins[counter]*coins[counter];
}
counter++;
}
string output="The amount can be changed by:\n";
for(int i=0;i<sizeof(coins);i++)
{
if(noOfCoins[i]>0)
{
ostringstream oss;
ostringstream oss1;
oss<<coins[i];
oss1<<noOfCoins[i];
if(noOfCoins[i]>1) output+="\t\t\t"+oss1.str()+" nos of "+oss.str()+" taka notes \n";
else output+="\t\t\t"+oss1.str()+" no of "+oss.str()+" taka note \n";
}
}
cout<<output<<endl;
return 0;
}
The result is okay for almost any integers like 34, 37829, ... etc, but the problem arises when the user inputs a number that ends in 6 like 6, x6, xx6, xxx6 etc.
There are 3 issues I see with your code.
First, the obvious one:
You are misusing sizeof:
int noOfCoins[sizeof(coins)]= {0};
This should be:
const int numCoins = sizeof(coins) / sizeof(coins[0]);
int noOfCoins[numCoins]= {0};
Then from there, you can use numCoins for the rest of the code:
for(int i=0;i < numCoins; i++)
The reason why sizeof(coins) did not work is that sizeof returns the size in bytes.
So if you have an array of 6 ints, the sizeof the array is sizeof(int) * 6, which is (assuming you are using 4 byte integers), 24. That goes way beyond the bounds of your array, thus you get undefined behavior.
Second issue: Faulty while() loop condition:
In the while loop condition, you're only testing for amount > 0. But what if amount is a large value? Your while loop will increment counter to beyond the bounds of your array, and you will be using counter as an index in your coins array, thus accessing beyond the bounds of the array.
The while loop should have this condition:
while (amount > 0 && counter < numCoins)
Third issue: Faulty test logic for the right coinage amount
You do this:
if (amount > coins[counter])
But this is wrong. What if the amount entered is simply 100? You miss the check for the 100 note using the above condition. This simply needs to be changed to this:
if (amount >= coins[counter])