cout pointer to array item is printing out different value than expected - c++

Why is it that my pointer value doesn't change when I print it to the console using this method:
int main()
{
int array[] = {1, 2, 3, 4, 5};
int *p = array;
p++;
*p = 100;
for ( int i = 0; i < 5; i++)
{
cout << *array + i << ", ";
}
return 0;
}
when I print this to the console I get 1, 2, 3, 4, 5. What is the pointer actually pointing to in this instance? In this example array[1] should have the value of 100 but it doesn't change.
I also know that if I start the array at 5 for example, the counter will just print in order up from 5. What is happening behind the scenes to cause this to happen?

*array resolves to the first element of the array. *array + i adds i to that element because due to operator precedence it is parsed as (*array) + i. So your loop prints 1 + 0, 1 + 1, etc.
If you want to print the elements of the array, you can do this:
for (auto e : array) cout << e << ", ";
If you want to use pointer arithmetic explicitly, the you will have to use parentheses in the right places:
for ( int i = 0; i < 5; i++)
cout << *(array + i) << ", ";

You're printing array[0] + i i.e. 1 + i for i in [0, 5). No way has binary + operator higher precedence than unary *. Use parentheses around + to form the right expression:
*(array + i) // or array[i]

Try
cout << *(array + i) << ", ";

Related

How does this overloading of square brackets work [duplicate]

This question already has answers here:
How does cout << " \n"[i == n - 1]; work?
(2 answers)
Is literal string indexing standard C?
(3 answers)
Closed 3 days ago.
I want to avoid printing space (" ") or an underscore ("_") after the last element of an array while printing them using a for loop. The problem mentions one of the way to do so, I want to understand how and why this happens.
vector<int> v1 = {1, 2, 3, 4, 5};
int n = v1.size();
for (int i = 0; i < n; i++) {
cout << v1[i] << "_"[i==n-1];
}
this prints 1_2_3_4_5 which is as expected.
I want to get around the working of this operator. How it functions and what other aspects does it cover.
There is nothing special going on with [] here. Its the usual element access. "_" is a const char [2] where first character is _ and the second is a null terminator \0.
You could do the same with a string:
vector<int> v1 = {1, 2, 3, 4, 5};
int n = v1.size();
for (int i = 0; i < n; i++) {
cout << v1[i] << std::string{"_"}[i==n-1];
}
Note, that std::string is an excepetion among containers and it is ok to read the \0 from str[str.size()].
\0 is not a printable character, hence you see the output you see.
Perhaps the code more clear if you use an empty string explicitly:
vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<std::string> d{ "_",""};
int n = v1.size();
for (int i = 0; i < n; i++) {
cout << v1[i] << d[i==n-1];
}
Alternatively, as you are using an index based loop anyhow (rather than a range based loop, which should be prefered), you can start the loop at the second element:
std::vector<int> v1 = {1, 2, 3, 4, 5};
std::vector<std::string> d{ "_",""};
int n = v1.size();
if (n) std::cout << v1[0];
for (int i = 1; i < n; i++) {
std::cout << "_" << v1[i];
}
In this statement
cout << v1[i] << "_"[i==n-1];
the expression "_"[i==n-1] is an expression with the string literal "_".
String literals have types of constant character arrays. The literal "_" has the type const char[2] and is represented in memory like
{ '_', '\0' }
So the expression "_"[i==n-1] uses the subscript operator with the string literal that is with an array. The expression i == n-1 is always equal to false that is converted to integer 0 when i is not equal to n-1. Otherwise it is equal to true that is converted to 1.
So you have either "_"[0] that yields the character '_' or "_"[1] that yields the character '\0';.
That is when i is not equal to n-1 you in fact have
cout << v1[i] << '_';
and when i is equal to n -1 you in fact have
cout << v1[i] << '\0';
Pay attention to that in this expression "_"[i==n-1] the string literal is implicitly converted to pointer to its first element.
Alternatively you could write with the same effect
vector<int> v1 = {1, 2, 3, 4, 5};
int n = v1.size();
const char literal[] = "_";
for (int i = 0; i < n; i++) {
cout << v1[i] << literal[i==n-1];
}
To enlarge your knowledge bear in mind that this expression "_"[i==n-1] you may also rewrite like ( i == n-1 )["_"] though such an expression will only confuse readers of the code.
From the C++17 Standard (8.2.1 Subscripting)
1 A postfix expression followed by an expression in square brackets is
a postfix expression. One of the expressions shall be a glvalue of
type “array of T” or a prvalue of type “pointer to T” and the other
shall be a prvalue of unscoped enumeration or integral type. The
result is of type “T”. The type “T” shall be a completely-defined
object type.66 The expression E1[E2] is identical (by definition) to
*((E1)+(E2)) [ Note: see 8.3 and 8.7 for details of * and + and 11.3.4 for details of arrays. — end note ] , except that in the case of an
array operand, the result is an lvalue if that operand is an lvalue
and an xvalue otherwise. The expression E1 is sequenced before the
expression E2.
Pay attention to that this code snippet
vector<int> v1 = {1, 2, 3, 4, 5};
int n = v1.size();
for (int i = 0; i < n; i++) {
cout << v1[i] << "_"[i==n-1];
}
could look more clear using the range-based for loop. For example
std::vector<int> v1 = {1, 2, 3, 4, 5};
bool next = false;
for ( const auto &item : v1 )
{
if ( next ) std::cout << '_';
else next = true;
std::cout << item;
}
If the compiler supports the C++20 Standard then you can write also like
std::vector<int> v1 = {1, 2, 3, 4, 5};
for ( bool next = false; const auto &item : v1 )
{
if ( next ) std::cout << '_';
else next = true;
std::cout << item;
}
your problem has nothing todo with the subscript operator though
you just need to figure out when to print the _ or not based on the position in the array when printing.
#include <vector>
#include <iostream>
// using namespace std; ehr no don't do this
int main()
{
std::vector<int> v1{ 1, 2, 3, 4, 5 };
for (std::size_t i{ 0ul }; i < v1.size(); ++i)
{
if (i != 0ul) std::cout << "_";
std::cout << v1[i];
}
std::cout << "\n";
// with vector use range based for if you can
// and then it becomes
bool print_underscore = false;
for (const int value : v1)
{
if (print_underscore) std::cout << "_";
std::cout << value;
print_underscore = true;
}
std::cout << "\n";
return 0;
}

Different result in Visual Studio 2019 and Linux

My code works perfectly in visual studio and Linux but i encounter a problem running it in Linux.
The function is about a dynamic array with a header file.
When I input number N, it prints prime numbers between 2 and N
Output:
I got only prime numbers under 10, when I used Linux.
Same code but different result!!
Please help me to know how I can get it fixed.
This is a part of the function:
#include <iostream>
#include "sieve.h"
#include <cstring>
using namespace std;
//prints all the prime numbers between 2 and N
Sieve::Sieve()
{
cout << "Enter the number of integers to input: ";
cin >> N;
arr = new bool[N + 1];
memset(arr, true, sizeof(arr));
for (int p = 2; p * p <= N; p++)
{
if (arr[p] == true)
{
for (int i = p * p; i <= N; i += p)
arr[i] = false;
}
}
return;
}
void Sieve::show()
{
cout << "Following are the prime numbers between 2 and "
<< N << endl;
for (int p = 2; p <= N; p++)
if (arr[p])
cout << p << " ";
cout << endl;
}
Sieve::~Sieve()
{
delete[] arr;
}
memset comes from C, and is generally incompatible with bool. It sets the memeory to a bitpattern, specifically static_cast<unsigned char>(true). There's no gurantee that static_cast<unsigned char>(true) has the same bitpattern as true.
std::fill works with pretty much any element type and any container.
sizeof(arr) would never be equal to size of your allocated array. It would be equal to sizeof(bool*) if arr is a pointer or if arr is some compound type that accepts pointer assignment, it's some different value, just never right one ...
Do not use memset for bools. On some platform true might have "all ones" binary pattern, on other it is just 1, sizeof(bool) may vary from 1 to 4 bytes. Use range-base filling (e.g. std::fill or plain for-loop), where arr would be the "begin" of the range and arr + N + 1 would be the "end".

In C++, how can I write a function that flips a 2d array at a specified position?

For my 2d array in C++, the 2d array needs to be flipped at a certain position. I have to write a function that flips the array
Foe instance,
Before:
double A[][2] = {{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}}
A B C D
call function invert(or flip): invert(A, 8, 3, 4);
after:
double A[][2] = { {0, 0}, {1, 1}, {2, 2},{6, 6}, {5, 5}, {4, 4}, {3, 3}, {7, 7}}
D C B A
Here is the attempt I have tried
#param A is the list of locations (x,y) of the cities in the current tour.
#param n is the number of cities in A.
#param start is the index of the beginning of the section to be inverted.
#param len is the length of the segment to invert(or flip).
void invert ( double A[][2], int n, int start, int len ) {
int(*tmp)[2] = new int[][2];
for(int i = 0; i >= A.length; i--){
for(int j = 0; j >= A[i].length; j--){
if( i > start)
tmp = A[i][j];
}
}
for(i = start; i < A.length; i++)
for(j = start; j < A[i].length; j++){
while (i <= end){
tmp = A[i][j];
}
}
}
The errors I have are
expressions must have class type
a value of type double cannot be assigned to an entity of type "double(*)[2]
cannot determine which instance of overload function "end" is intended
I am fully aware that most of the errors in my code are evident to find, but I needed to start somewhere.
I admit, I don't know how to do it with a 2D C-array. I can only tell you about the simple way to do it.
First, a general advice: Name your stuff. What if I had to read only your code to see that you are dealing with locations of cities, that have x and y coordinates, instead of having to read your text, wouldn't that be great?
Next, for resizable arrays, you can (/should) use std::vector instead of C-arrays. C-arrays decay to pointers when passed to functions. C-arrays have their size as part of their type, but it is inconvenient to access it (and impossible once decayed to a pointer). And manually resizing dynamic C-arrays isn't much fun either.
Eventually, the "simple way" is to use an existing algorithm. To reverse elements in a range it is std::reverse:
#include <iostream>
#include <vector>
#include <algorithm>
struct location {
int x;
int y;
};
int main() {
std::vector<location> cities{{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}};
for (const auto& loc : cities){
std::cout << loc.x << " " << loc.y << "\n";
}
std::cout << "\n";
std::reverse(cities.begin()+ 3,cities.begin() + 7);
for (const auto& loc : cities){
std::cout << loc.x << " " << loc.y << "\n";
}
}
Output:
0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
0 0
1 1
2 2
6 6
5 5
4 4
3 3
7 7
Actually with a 1-D c-array it is almost the same. The major difference is that c-arrays do not have begin as member. This produces same output as above:
location cities2[] = {{0,0}, {1,1}, {2,2}, {3,3}, {4,4}, {5,5}, {6,6}, {7,7}};
for (const auto& loc : cities2){
std::cout << loc.x << " " << loc.y << "\n";
}
std::cout << "\n";
std::reverse(std::begin(cities2)+ 3,std::begin(cities2) + 7);
for (const auto& loc : cities2){
std::cout << loc.x << " " << loc.y << "\n";
}
And if you want to wrap it in a function you need to take care of the array decaying to a pointer:
void my_reverse(location* loc, size_t len, size_t first, size_t last){
std::reverse(loc + first, loc + last + 1);
}
(I choose last to be the last element to be reversed. Note that the algorithm takes an iterator to the element one past the last element to be reversed).
Complete example with all three variants: https://godbolt.org/z/WMdea7WP3
That's how I'd write the function if I knew it would always be used with 2 column arrays
void invert(double cities[][2], int size, int start, int len) {
if (size < 0 || len < 0)
return;
double tempCoordsX, tempCoordsY;
int endPos = start + len - 1;
for (int i = start; i < (start + len/2); i++) {
int mirroredPos = (endPos - (i - start)) % size;
tempCoordsX = cities[i][0];
tempCoordsY = cities[i][1];
cities[i][0] = cities[mirroredPos][0];
cities[i][1] = cities[mirroredPos][1];
cities[mirroredPos][0] = tempCoordsX;
cities[mirroredPos][1] = tempCoordsY;
}
}
I repeat: please name your stuff

Checking the neighbour values of arrays

I have an array of numbers with length L, and I have to make the program check the sums of every array element with its preceding and following neighbors.
So, for example, if I have the array being {1, 2, 3}, the output for the 2nd element should be 6 because 1 + 2 + 3 = 6 and they are all neighbors.
If the chosen element is the first element in the array, its preceding neighbor is the last element of the array, and if the element is the last element in the array, the following neighbor is the first element of the array. So, in the {1, 2, 3} example, no matter what number you check, you always get 6, but if it were {1, 2, 3, 4} instead, the answer for the 3rd element would be 9 because 3 + 2 + 4 = 9.
I hope you understood how it should work.
The problem I am getting is that the output is out of control. I tried to check the array itself and it is completely normal. In the {1, 2, 3} example, I get an output of 7208681 and I don't know why.
#include <iostream>
using namespace std;
int main()
{
int total;
cin >> total;
int Bush[total]; //array of numbers
int temp, output = 0; //output variable and a container for the last resurt a.k.a temp
for (int i = 0; i <= total - 1; i++)
{
cin >> Bush[i]; //inputting the array elements
}
for (int i = 0; i < total; i++)
{
if (i == 0)
output = Bush[i] + Bush[i + 1] + Bush[total]; //checking if the loop checks the first number
if (i == total - 1)
output = Bush[i] + Bush[0] + Bush[i - 1]; //checking if the loop checks the first number
temp = output; //assigning the temp value to the current output value
output = Bush[i] + Bush[i + 1] + Bush[i - 1]; //assigning a new output value
if (temp > output)
output = temp; //checking values
}
cout << output << endl; //outputting
return 0;
}
When i = 0, the expression Bush[i-1] results in accessing an invalid location of the array (- 1).
Similarly, when i = total - 1 (last index of iteration), the expression Bush[i+1] gives you an index of total which is out of bounds of the array.
The last element of Bush is at index total -1, but you are accessing Bush[total] when i==0
At the end, there are many mistakes in your code, nonetheless, the problem with the if/else structure.
I would suggest you to use another inner loop, based on module operator that simplify the code a lot:
int max = 0;
for(int i = 0; i<total; i++)
{
output = Bush[i] + Bush[(i+1)%total] + Bush[(i-1+total)%total];
if(max < output) max = output;//checking the max
}
cout<<max<<endl;//outputting
that does the operation you required.
Hope this may help.
I think the below code would work
int main()
{
int total;
cout << "Enter Number of Elements " << endl;
cin>>total;
int Bush[total];//array of numbers
int temp = 0, output = INT_MIN; //output variable and a container for the last resurt a.k.a temp
cout << "Enter the Elements " << endl;
for(int i = 0; i<=total - 1; i++)
{
cin>>Bush[i];//inputting the array elements
}
for(int i = 0; i<total; i++)
{
if(i == 0)
temp = Bush[i] + Bush[i+1] + Bush[total -1];//checking if the loop checks the first number
else if(i == total - 1)
temp = Bush[i] + Bush[0] + Bush[i-1];//checking if the loop checks the first number
else
temp = Bush[i] + Bush[i+1] + Bush[i-1]; //assigning the temp value to the current output value
output = (temp > output)?temp:output;
}
cout<<output<<endl;//outputting
return 0;
}

Lint warning Suspicious Truncation in arithmetic expression combining with pointer

I have the following code:
int array[128][3] = { /*lots of emelents there*/}
int* listIt = &array[0][0];
for(unsigned int index = 0 ; index < 128; index++)
{
printf("%x", array[index*3 + 1]);
}
but I got lint warnings like:
Suspicious Truncation in arithmetic expression combining with pointer
Then I changed the code to
array[index*3 + 1u];
still get warnings, can someone help me on that?
Try the following:
1) change literal 3 to unsigned, as you did for 1;
2) use indexing in 2D-array style: array[row][col] instead of array[row*col+1].
Lint's warning is correct you are going to index out of bounds with this code.
The line: printf("%x", array[index*3 + 1]); Will look at array[index * 3 + 1]. When index is 44, index * 3 + 1 is 133. array only has 128 int[3] elements this is out of bounds.
It appears that you are trying to print the addresses of the start of each int[] in array. Try this instead:
for(auto it = begin(array); it < end(array); ++it){
cout << *it;
}
Not sure but you may be trying to print the contents rather than the address of each int[3] in array. If so you could accomplish that like this:
for(auto it = begin(array); it < end(array); ++it){
cout << (*it)[0] << ", " << (*it)[1] << ", " << (*it)[2] << endl;
}