I tried to input two array numbers, A and B. But every time I input the last B number, besides it changed the value of B[i+n], it also replace the value of A[0]
Here is the code:
#include <iostream>
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
int a[] = {};
int b[] = {};
int t, i;
cout << "Amount of numbers: ";
cin >> t;
for (i = 0; i < t; i++) {
cout << "Enter number for A" << i+1 << ": ";
cin >> a[i];
cout << "Enter number for B" << i+1 << ": ";
cin >> b[i];
}
for (i = 0; i < t; i++) {
cout << a[i] << " ";
cout << b[i] << " ";
}
return 0;
}
For example
Amount of numbers: 2
Enter number for A1: 1
Enter number for B1: 2
Enter number for A2: 3
Enter number for A3: 4
The output supposed to be 1 2 3 4, but from the code I got 4 2 3 4 (the B[1] replace the value of A[0].
Can someone help me to fix this? Thanks
The problem is that you are using a two stack allocated arrays with unspecified size, which is 0 since you initialize them with { }.
These arrays are not dynamic, you can't add elements like you are doing. Their size must be specified a priori directly or through initialization and it's reserved on the stack at compile time, which means that if you try to access an element of a over its size, then you'll end up in b since they are stored next to its other.
Use two std::vector<int> instead so that you can do
std::vector<int> a;
..
a.resize(t);
..
cin >> a[i]
You're allocating arrays without a size.
Try std::vector if you want dynamically sized arrays.
As others have mentioned, what is happening is that you are allocating empty arrays in the stack, and then accessing past the bounds of said array. This has far more dire consequences than you may at first realize.
The first of which is, as #Jack mentioned, that writing past a[0] will start writing in b, giving you duplicate and nonsensical values at the end of your program. Perhaps less obvious is the fact that you will also start overwriting t and i, since they are allocated in the stack after a and b. To illustrate my point, look at the output below:
Amount of numbers: 2
Enter number for A1: 1
Enter number for B1: 2
Enter number for A2: 3
Enter number for B2: 4
Enter number for A3: 5
Enter number for B3: 6
a[0] 0x7fffffffe2e0 -> 1
b[0] 0x7fffffffe2e4 -> 3
a[1] 0x7fffffffe2e4 -> 3
b[1] 0x7fffffffe2e8 -> 5
a[2] 0x7fffffffe2e8 -> 5
b[2] 0x7fffffffe2ec -> 2
a[3] 0x7fffffffe2ec -> 3
b[3] 0x7fffffffe2f0 -> 4197280
a[4] 0x7fffffffe2f0 -> 4197280
b[4] 0x7fffffffe2f4 -> 0
t 0x7fffffffe2e8 -> 5
i 0x7fffffffe2ec -> 5
You'll note that the program does not behave as expected, and you are prompted for A/B3, not just the expected 2. That is because t is overwritten when b[1] or a[2] are written to, as they all correspond the the same address, which of course makes the loop condition fail.
To allocate arrays in the stack, a size has to be provided at compile time. int a[10], etc. This is used when the size is known prior to execution. If the size unknown, as is your case, you can allocate an array in the heap with new[], as below.
cout << "Amount of numbers: ";
cin >> t;
int* a = new int[t];
int* b = new int[t];
Which will of course give you the expected results:
Amount of numbers: 2
Enter number for A1: 1
Enter number for B1: 2
Enter number for A2: 3
Enter number for B2: 4
a[0] 0x603010 -> 1
b[0] 0x603030 -> 2
a[1] 0x603014 -> 3
b[1] 0x603034 -> 4
t 0x7fffffffe2d8 -> 2
i 0x7fffffffe2dc -> 2
The recommended solution is, of course, to use an std container, namely std::vector, where the heap allocation is done for you, and you can simply write:
std::vector<int> a;
std::cin >> input;
a.push_back(input);
The zero size arrays are not valid in C++, and this code doesn't compile with the two compilers I tried.
Instead of raw arrays you can use std::vector.
With std::vector you can use the push_back member function to add items at the end.
Related
I'm taking an elementary programming course where we use C++ and I'm stuck on a couple of assignments. Please excuse my potentially bad terminology going forward. Part of my basic program I'm writting asks "Write down 5 integers: " and then the user gets to pick the integers and a message "You wrote the integers: n1 n2 n3 n4 n5" is returned. There are several of these questions and I'm not allowed to use more then one variable of the same type. The problem is that the user could respond with n1 n2 n3 n4 n5 hello, and hello is supposed to be ignored. How do I accomplish this?
If we for a moment assume that we are only to write down one integer instead of 5, then perhaps something along the lines of the code below would work.
#include <iostream>
using namespace std;
int main()
{
int num;
cout << "Write down an integer: "
<< flush;
cin >> num;
cout << "You wrote the integer: "
<< num
<< endl;
}
But how do I do this with five integers. Further, how do I ignore that extra hello? I'm assming that cin.ignore is to be used here somehow.
If you want to repeat the procedure 5 times, you could just copy-paste it, but that's definitely not a good practice. What's much better is to use a loop/cycle, like for.
You'll also need to store all 5 integers into memory. You could use 5 variables (int n1, n2, n3...), but again, that's not a very good practice and as you state, that's not allowed in your case. Solution is to use an array, which can hold several values of the same type.
Here is a working example with explaining comments:
int nums[5]; // this array will hold 5 integers
int n;
cout << "Write down 5 integers:" << endl;
for (n = 0; n < 5; ++n) { // run code in the braces 5 times
cin >> nums[n]; // store typed integer into nth position of the array
}
cout << "You wrote: ";
for (n = 0; n < 5; ++n) { // run code in the braces 5 times
cout << nums[n] << " "; // print integer at nth position of the array
}
Note: One could say that both nums and n are of the same type, int. In that case, you could extend the array nums to the size of 6 items and use the last one (to which you can refer as nums[5]) as an indexing variable for the loops.
I'm creating a simple quick sort program that initializes an empty array and asks the users for inputs to determine how many elements are going to be sorted and what elements are going to be sorted.
The problem I am encountering is a local variable is being changed despite being only being referenced to once assigned. Attached below is the code.
int main()
{
int amount;
int numbersarray[] = {};
std::cout << "How many numbers do you want to sort? " << std::endl;
std::cin >> amount;
for(int i = 0; i <= amount; i++){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
std::cout <<"Amount to be sorted: " << amount << std::endl;
for(int i = 0; i <= amount; i++){
std::cout << numbersarray[i] << std::endl;
}
}
What I expect to be occurring, when I input the amount as 5, I should be able to input 5 elements into the array, instead however the Amount printed is 2 and the maximum elements I can put into the array is 3.
Below is the execution output.
How many numbers do you want to sort?
5
Enter number to be sorted:
5
Enter number to be sorted:
2
Enter number to be sorted:
5
Amount to be sorted: 2
5
2
5
I've tried messing around with the for statement but I don't think I'm doing it right as it hasn't fixed the problem, The manipulation of the for statement I'm doing is changing the condition (i.e !=, <, <=)
You have undefined behavior. Anything can happen. Local variable can change without reason, the program can crash and your computer can format itself with linux 6.9
There are many problem. The first is that your program is invalid according to the standard:
int numbersarray[] = {};
This is not valid. Array need a size:
constexpr int max_amount = 32;
int numbersarray[max_amount] = {};
If you need it to be dynamic, use vector:
std::vector<int> numbersarray;
numbersarray.resize(amount);
Second, you have another source of undefined behavior:
// Iterates too much, numbersarray[amount] is past the end
// ~~~v~~~~~~~
for(int i = 0; i <= amount; i++){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
It should be:
for(int i = 0; i < amount; i++){
std::cout << "Enter number to be sorted: " << std::endl;
std::cin >> numbersarray[i];
}
To avoid invalid code and undefined behavior, you should enable warnings.
numbersarray is a C-style array with a size of zero and doesn't adjust its size dynamically (most compilers might even fail to compile int numbersarray[] = {}; since an empty initializer isn't allowed for an array with unspecified size).
Writing or reading its elements causes undefined behaviour (which can be access violations, changing unrelated variables, and much more). This is the reason why you might see the values of local variables changing. Someone else that uses the same code could get completely different behaviour, since it is undefined.
I'd like to ask you if you think about this code, whether it is totally bad or i'm doing a bad use of the memory
This is the code
// Ask for capacity
int capacity ;
cout << "capacity: ";
cin >> capacity;
// Declare the array with pointers, this line is very important
int *arr = new int;
// For 0 until capacity-1 print ask for the numbers
for (int i = 0; i < capacity; i++)
{
cout << "number: ";
cin >> *(arr + i);
}
// Print them
for (int i = 0; i < capacity; i++)
{
cout << "[" << i << "]: " << *(arr + i) << " in " << arr + i << endl;
}
And this is an example of its output
capacity: 9
number: 1
number: 2
number: 3
number: 4
number: 5
number: 6
number: 7
number: 8
number: 9
[0]: 1 in 0x55dee480c690
[1]: 2 in 0x55dee480c694
[2]: 3 in 0x55dee480c698
[3]: 4 in 0x55dee480c69c
[4]: 5 in 0x55dee480c6a0
[5]: 6 in 0x55dee480c6a4
[6]: 7 in 0x55dee480c6a8
[7]: 8 in 0x55dee480c6ac
[8]: 9 in 0x55dee480c6b0
Look that, effectively it's saving the numbers in the correct positions in memory (4 bits, the size of an int)
But what's the limit? How can I know if I'm touching memory that I shouldn't touch?
Because look that I'm declaring the array as
int *arr = new int
Is that okay?
the same with this code, but this could be a little bit worse because it's a string, an array of characters as you may know
// Declaring the pointer name as new char and ask for it
char *name = new char;
cout << "name in: ";
cin >> name;
cout << "name out\n";
for (int i = 0; *(name + i) != '\0' ; i++)
{
printf("[%i]: %c\n", i, *(name + i));
}
Example:
name in: Gilberto
name out
[0]: G
[1]: i
[2]: l
[3]: b
[4]: e
[5]: r
[6]: t
[7]: o
The code only allocates one int object. Fix:
int* arr = new int[capacity];
*(arr + i) can be simpler: arr[i].
The code needs to delete the array at the end:
delete[] arr;
Or, better, use a smart pointer to avoid having to delete manually:
std::unique_ptr<int[]> arr(new int[capacity]);
Or, even better, use std::vector<int> arr(capacity);.
Raw (owning) pointers and manual memory management is almost never a good idea in modern C++. You should use containers like std::array and std::vector rather than C-style arrays any day. And ownership and lifetime of dynamic resources is much better modeled with smart pointers like std::unique_ptr, std::shared_ptr & std::weak_ptr rather than raw pointers. Don't write code that's easy to get wrong. Use the facilities we have available, to write code that's easy to get right and hard(er) to get wrong.
I'm new to the community and to coding as well. Right now I'm taking Intro to Computer Science at my CC and we're learning C++. Anyways, I have to create a program which asks the user for a number, which will be the size indicator of the array new_array. The program then asks the user to input the numbers one by one and afterwards, outputs them in reverse.
#include
using namespace std;
int main()
{
cout << "How many numbers?\n";
int numbers; // holds amount of numbers to be entered into array
cin >> numbers;
int new_array[numbers];
for(int counter = 0; counter < numbers; counter++)
{
cout << "Enter number " << counter << endl;
cin >> new_array[counter];
}
cout << "You entered: " << endl;
for(int i = numbers; i >= 0 ; i-- )
{
cout << new_array[i] << endl;
}
return 0;
}
I understand how to do this and for the most part, my program worked. It outputs the numbers entered in reverse just fine, but before it does so, it outputs large, strange numbers. For example, if the user enters 5 as the amount of numbers to be entered, and then enters 1, 2, 3, 4 and 6 as the 5 numbers respectively, the program outputs the number 4669476 first and then outputs the numbers in the array in reverse. Can anyone explain to me what I did wrong and how I could fix this? Thank you in advanced!
PS be gentle! I'm a newbie at this
This loop reads out of bounds:
for(int i = numbers; i >= 0 ; i-- )
{
If you follow i through in your head you will see that you output entries numbers through to 0, when in fact you should output entries numbers-1 through to 0.
An alternative patterns is:
for( int i = numbers; i--; )
Or you can use the fabled --> operator.
It would be possible to "simply" start from numbers - 1, however the loop pattern you have used would not work for an unsigned counter (because they are always >= 0). IMHO it is a good idea to use a pattern which works for all types; then you are less likely to make a mistake in future.
In your display for loop, you started from i = numbers which is out of the array's range. Since the array starts from 0 till size - 1, then you need to start from i = numbers - 1 all the way to >=0.
Because you start from array[numbers] which is not defined.
array[0], array[1], ... array[numbers-1] are defined.
In C arrays are stored from 0 instead of 1. So the last number is stored in array[4]
So when you're writing it out you should start an numbers - 1 instead of just numbers.
Because you are starting the index from out of range giving you garbage value.
your code should look some thing like this
for(int i = numbers-1; i >= 0 ; i-- )
{
cout << new_array[i] << endl;
}
I am a beginner in C++. I am trying this long integer multiplication. I am not understanding that how the value ofsum[3][0] is changing in the subsequent loop cycle.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string num1, num2;
int i,j,l1, l2,temp,k;
cout << "Enter first number: ";
cin >> num1;
cout << "Enter second number: ";
cin >> num2;
l1= num1.size();
l2= num2.size();
cout << l1 << " " << l2 << endl;
int sum[l2-1][l2]; // 5 6 7 8 ---> num1
// 1 2 3 4 ---> num2
for(i=0; i<l1; i++) // ---------
num1[i]-='0'; // 2 2 7 1 2 sum[3][4]---->sum[3][0]
// 1 7 0 3 4 i.e sum[3][0] should be 2
for(i=0; i<l2; i++) // 1 1 3 5 6
num2[i]-='0'; // 5 6 7 8
// -------------
for(i=l2-1; i>=0; i--) // 7 0 0 6 6 5 2
{
k=0;
temp=0;
for(j=l1-1; j>=0; j--)
{
temp+=(num2[i]*num1[j]);
sum[i][k]= temp%10;
temp=temp/10;
k++;
}
sum[i][k]=temp;
cout << sum[3][0] << endl;
}
for(i=l2-1; i>=0; i--) // output is 2 2 7 1 1 Here value of sum[3][0] is 1 but the desired output is 2.
{ // 1 7 0 3 1
for(k=l2; k>=0; k--) // 1 1 3 5 0
cout << sum[i][k]; // 0 5 6 7 8
cout << endl;
}
return 0;
}
I tried this code for the case num1=5678 and num2=1234. So sum[3][0] should be 2 in that case.
You did not make sum large enough. You use sum[0..l2-1][0..l1] so the size would need to be sum[l2][l1+1].
When you exceed the second dim of sum that typically makes part of one row of sum share storage with part of another, so the place where you stored sum[2][0] is the same place you later stored sum[1][4]
When you exceed the first dim of sum (or the second dim in the last row) that makes sum share storage with other things, such as(but not necessarily) the other variables local to that function.
Also, your loop for displaying sum is incorrect. You use rows of sum from l2-1 down to 0 and columns from 0 up to L1. But you display columns l2 down to 0. The columns are computed based on l1, so should be displayed based on l1. That error would have symptoms if you tried an example with l1 not equal l2.
The sum array should be create like this:
int sum[l2][max(l1,l2)+1];
It is too small to store results of you calculations now.
Why program doesn't crash while you write out of bounds of the array? Because C++ has not any array bounds checking.
To be honest, you should declare the array by new and remove it by delete when it is not needed anymore. C++ standard doesn't provide to create non-constant size array without new. Only some compilers supports it as an extension and many of them prints warnings when you do that. More informations here: How do I declare a 2d array in C++ using new?