Printing array of doubles gives unexpected results - c++

In a program I am writing I am experiencing unexpected output when printing data from an array. I have tried with float and double. Here is the code:
#include <iostream>
int main()
{
double vector[3]{ 193.09375 , 338.5411682 , -4.0 };
double pVecX{ 193.09375 };
double pVecY{ 338.5411682 };
double pVecZ{ -4 };
std::cout << std::dec << vector[1] << '\n' << vector[2] << '\n' << vector[3] << '\n' << '\n';
std::cout << std::dec << pVecX << '\n' << pVecY << '\n' << pVecZ << '\n';
system("Pause");
return 0;
}
This is the output:
338.541
-4
1.42292e-306
193.094
338.541
-4
Press any key to continue . . .
Issues:
I expected the vectors to print in reverse order from how they were entered into the array.
(Even though I ask for [1]..[2]..[3], it is printing [2]..[3]..[1] (I Think that is the order))
When part of the array, the number "193.09375" becomes a (seemingly) random notated number, and is different every time the program runs.
I was reading about variables and understand that a variable stored outside of the range it is initialized as can cause wrap-around, I just do not know why that is happening here. (I assume it is based on the negative notation.)
I am certain that I am missing something simple, and I am fairly new.

An Arrays index starts at 0. So when you say vector[3] you are actually going out of bounds.
You only have 0, 1, and 2 indices or subscripts. Although you do have 3 elements. 0 would refer to your first element, 1 would refer to your second element, and 2 would refer to your 3 element, and so on and so forth.
(Like I mentioned in my comment.)
You should have something like this instead:
std::cout << std::dec << vector[0] << '\n' << vector[1] << '\n' << vector[2] << '\n' << '\n';
This should fix your problem. Also consider using a std::vector.
Also read about why you should not use system("Pause");.

As mentioned in other answers, the valid indexes for an array of size 3 is 0, 1, and 2. Using any other index invokes undefined behavior.
You can also avoid explicitly indexing into the array, if you use a loop:
for (auto v : vector)
std::cout << std::dec << v << '\n';

vector[3] is outside the bounds of the array. Behaviour of the program is undefined. Valid indices are 0, 1 and 2.

I expected the vectors to print in reverse order from how they were entered into the array.
Why? The indexes you print are ordered from lower to higher (and the << print in the order of the source code, etc.). If you wanted to reverse them, you need to print first the highest index, 2, then 1, then 0,
When part of the array, the number "193.09375" becomes a (seemingly) random notated number, and is different every time the program runs.
The vector array goes from 0 to 2, not from 1 to 3. When you try to access vector[3], it is undefined behavior and the program will likely printing whatever memory ends up there. Every time you run the program that memory may contain different things, it is a fairly normal result of undefined behavior.

Arrays in C++ are zero indexed, that means that the first element is accessed by the index 0, e.g.
int array[3] {5,6,7};
So array[0] == 5, array[1] == 6, array[2] == 7.
The reason you get a random number is that you are trying to print an element of the array which never got defined. In the given example of my array above, if I would try to print element array[3], the corresponds to a certain place in memory (which is not part of my array) which can be filled by any value, thats called undefined bahavior).
If you want to print out every element of an array, you could make use of range based for loops:
for (auto a : my_array) std::cout << a << std::endl;

Related

Which is correct for sizing a vector

Hi I am just starting to learn cpp and I have two examples of getting the size of a vector in the for statements both seem to work but which is right and why? sizeof(vector) or vector.size()?
Thanks
Brian
void print_vector(vector<string> vector_to_print){
cout << "\nCars vector = ";
for(int i = 0; i < sizeof(vector_to_print); i++){
cout << vector_to_print[i];
(i < vector_to_print.size()-1) ? (cout << ", ") : (cout << endl); // ? the tenrary operator is an if statement (?) do one outcome (:) or the other
}
}
void print_vector(vector <string> vector_to_print){
cout << "\nVector contents = ";
for( int i = 0; i < (vector_to_print.size()); i++ ){
cout << vector_to_print[i];
(i < (vector_to_print.size()-1)) ? (cout << ", ") : (cout << endl);
}
}
Both seem to work I try to rewrite the same code from memory each day for a week to help me learn it and I couldn't quite get the sizeof() to work so I googled it and the example I found used .size() but when I got home and checked what I did yesterday I had used sizeof().
std::vector<std::string> is a container class, which stores an array of std::strings plus other values to assist with manipulation of the array and providing information about the state of the stored array. When you call sizeof(vector_to_print) you are simply getting the size of the container class not the amount of elements in the array that it is storing.
run the following code to prove it to yourself:
std::vector<std::string> vec{"hello","world"};
std::cout << sizeof(vec) << '\n';
vec.push_back("!");
std::cout << sizeof(vec);
the size of the underlying array is changing it goes from 2 elements to 3, but not only does the sizeof(vec) not change, it is always = to 24!
sizeof(vec) must be the same each time (24 bytes on my machine) because sizeof is a compile time constant, because the size of a type must be a compile time constant.
The latter (.size()) is the only valid method
As you already know there are classes in C++. One class can have many methods doing different things and many fields holding different things. When we create an object of class Vector this object has method .size() which as mentioned here returns the number of elements in our object. The complexity is Constant and there is no problem using .size().
When you are using sizeof() as mentioned here on our object you know the size of the object with all its fields (for example vector can have size_t field where it counts all the elements and some field which holds them) you don't need the actual size of the vector in order to iterate the elements this could be wrong in many cases.
P.S. You must use .size()!

Correctly reading a known number of integer inputs into a vector in C++

I'm new to C++ and wanted to make a small function today which would flip all the elements of an array that was given to it (I had a pretty good idea for it). I started using arrays, but ran into issues since only a pointer to the first element is passed to the function; it was giving some very strange output. It was recommended I use a vector instead, but that started to give me some really odd output, too. I added a cout iterating over the vector values to see what it contains for some sanity-checking, but the outputs are completely bizarre; looks like I'm struggling to work out how to read input into it correctly.
As I mentioned, I first tried an array, which I could read into fine with a range-for loop. I tried that same thing with vectors (solution 1) and found it to be ignoring the first input, and assigning each element the last value that I gave it.
I first tried other Stack overflow threads but I found the solutions far too verbose or not suitable for something as simple as I need.
I thought maybe the vector couldn't be used in the range-for so I did for(auto x : array_size) instead - this gave an error stating there was no suitable "begin" for the function, so I changed this back.
Instead I looked around at the documentation and found .push_back(value) (solution 2) which appeared to put a given value at the end of the vector. Thought I might at least get some input into it correctly, which would be a step in the right direction. Instead, the output seems to show it doubled the number of positions in the vector and just assigned my first input to the furthest position. I imagine this is due to me specifying a size for the vector, and then having push_back grow the vector by that number of inputs (resulting in a double-size vector).
As for the input values themselves, I'm stumped.
Below is the offending bit of code as it stands with solution 2.
int main()
{
int array_size;
auto index_num = 0;
int arr_input = 0;
std::cout << "This program flips an array." << "\n";
std::cout << "Enter how many elements will be in your array: ";
std::cin >> array_size;
std::vector<int> user_array (array_size);
std::cout << "Fill your array with integer values. Press 'Enter' after each: " << std::endl;
for(auto x : user_array)
{
std::cin >> arr_input;
user_array.push_back(arr_input);
}
index_num = sizeof(user_array) / sizeof(user_array[0]); //or just use array_size-1 instead?
std::cout << "Your array, unflipped, contains the values: " << "\n";
for(auto y : user_array)
{
std::cout << "[" << user_array[y] << "] ";
}
Solution 2 provides this output:
Fill your array with integer values. Press 'Enter' after each:
1
2
3
4
5
Your array, unflipped, contains the values:
[0] [0] [0] [0] [0] [0] [0] [0] [0] [1]
Solution 1, where I attempt to input directly into the n-th location of the vector (as I would with an array) provides this output (with the same five 1 - 5 inputs):
Your array, unflipped, contains the values:
[0] [5] [5] [5] [5]
No error messages, everything is perfectly legal, I clearly just don't understand how something simple like a vector is implemented here.
I haven't even got to the taxing bit yet - flipping the array! Any advice appreciated.
std::vector<int> user_array (array_size) creates a vector containing array_size zeros. You then use push_back which adds additional elements to the end. You need to create an empty vector using std::vector<int> user_array, and optionally with a capacity of array_size by calling user_array.reserve(array_size). Since your vector starts out empty now, you'll need to change for(auto x : user_array) to a non-range-based loop such as for (int i = 0; i < array_size; i++).
sizeof(user_array) / sizeof(user_array[0]) only works with plain C arrays, not vectors. Use array_size or user_array.size().
In the last range-based for loop, y is the values in the array, not the indices. So print y, not user_array[y].
You seem to be confusing std::vector with C-style arrays.
std::vector<int> user_array (array_size);
initializes user_array with array_size zeroes.
for(auto x : user_array)
{
std::cin >> arr_input;
user_array.push_back(arr_input);
}
As noticed by Alexander Zhang, this piece modifies the vector while iterating over it, which results in Undefined Behaviour. It could result in anything happeining in your program, including infinite loop, crashing completely, supposingly working correct or demons flying out of your nose
index_num = sizeof(user_array) / sizeof(user_array[0]); //or just use array_size-1 instead?
This line makes no sense. You can get the length of vector using its size() method: user_array.size();, but you don't use that variable anyway.
for(auto y : user_array)
{
std::cout << "[" << user_array[y] << "] ";
}
This loop makes no sense either. y is not an index in the vector, it is a value from that vector. If you have a vector {10, 20, 30}, then in first iteration y is equal to 10, in second iteration y is 20 and in third y is 30.
After fixing the errors, your code should look like this:
std::vector<int> user_array ();
std::cout << "Fill your array with integer values. Press 'Enter' after each: " << std::endl;
for(int i = 0; i < array_size; ++i)
{
std::cin >> arr_input;
user_array.push_back(arr_input);
}
std::cout << "Your array, unflipped, contains the values: " << "\n";
for(auto y : user_array)
{
std::cout << "[" << y << "] ";
}
Or for an (invisible) increase in performance, you can reserve the size of the vector before you read it:
std::vector<int> user_array ();
user_array.reserve(array_size);
std::cout << "Fill your array with integer values. Press 'Enter' after each: " << std::endl;
for(int i = 0; i < array_size; ++i)
{
int x;
std::cin >> x;
user_array.push_back(x);
}

Endiannes of machine and array elements storing

I am concerned about how arrays are stored in C. for example I have such array:
unsigned char array[] = {1, 0};
I have Little endian machine so as far as I know elements of this array will be stored in memory in reversed order like [0, 1].
But when i execute such code :
std::cout << (void*)&array[0] << std::endl;
std::cout << (void*)&array[1] << std::endl;
I will get two addresses. The second one will be bigger by one.
I don't understand this because if the 0 element will be placed first in memory and then 1, so why the address of first element of array (value 1) is lesser than second element (value 0).

Expression: vector subscript out of range C++?

I am trying to access a variable, and print it out. However, I encounter the Vector subscript out of range error.
I am doing
cout << myStruct->myVector[0].GetCoordinate(0) << endl;
where
myStruct points to a structure that contains a vector myVector of points. So I am trying to print out its first coordinate.
To debug:
cout << typeid(myStruct->myVector[0].GetCoordinate(0)).name() << endl;
gives me
float
and
cout << sizeof(myStruct->myVector[0].GetCoordinate(0)) << endl;
gives me
4
However, when I directly print its value
cout << myStruct->myVector[0].GetCoordinate(0) << endl;
Error message:
Your vector is empty. Any index that's not between 0 and .size() (excluding the latter) is out of range. Since there is no index between 0 and 0, every index is out of range.
You need to populate your vector first, e.g. use .resize or .push_back.
Issue caused by:
tlen = __byte_encode_array(buf, offset + pos, maxlen - pos, &this->data[0], this->size);
Impossible to access a non-existing element in a vector.

For loop condition is a variable without comparison

int a[5] = {1,2,3,4,5};
for (int i = 0; a[i]; i++)
{
cout << i;
}
This code produces the output of "0 1 2 3 4".
What does it compare a[i] against, and how does it know to stop at the end of the array and not go over?
You code causes undefined behaviour. The expression a[i] will evaluate as true if non-zero and as false if zero. When you run it, you're getting lucky that there is a 0 word immediately following your array in memory, so the loop stops.
It's reading past the array and the memory there just happens to be zero, by sheer luck. Reading past the end of that array is undefined behavior and the outcome might change at any time, so never rely on it.
You can think of a[i] as being compared to 0, it simply fetches the number retrieved from the location in memory and if 0 is the value that lives at that memory, then the loop exits, if it is any other number the loop continues.
Suppose an int is 4 bytes on the system. a is given an address, lets pretend it is 0xFF00 when we try to evaluate a[0] we retrieve the data value stored at memory 0xFF00. a[1] would retrieve data from memory 0xFF04, etc. Your program only assigns values to the first 5 memory locations, so when we retrieve the data at beyond these locations they could be anything from 0 to INT_MAX. If it happens to be 0 then the loop exits, however if it happens to be something else the loop continues.
Your could adjust your program like so to see it better:
#include <iostream>
using namespace std;
int main() {
int a[5] = {1,2,3,4,5};
int i;
for (i = 0; a[i]; i++)
{
cout << "At memory address: " << &a[i]
<< " lives the value: " << a[i] << endl;
}
cout << "At memory address: " << &a[i]
<< " lives the value: " << a[i]
<< ", and this is why the loop ended." << endl;
return 0;
}