Lint warning Suspicious Truncation in arithmetic expression combining with pointer - c++

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

Related

Why are variable length arrays in C++ overlapping on some sizes?

After providing an answer to a question here, I was testing this code that I edited and noticed some strange behavior:
#include <iostream>
#define MAX 100
using namespace std;
int main()
{
int size = 0;
int array[MAX];
int i, j;
int input;
cout << "Array: ";
for(i = 0; i < MAX; i++)
{
cin >> input;
if(input == -1)
break;
else
{
array[i] = input;
size++;
}
}
cout << "Size: " << size << "\n\n";
int left[size / 2];
int right[size / 2];
for(i = 0; i < size / 2; i++)
left[i] = array[i];
for(i = size / 2, j = 0; i < size; i++, j++)
right[j] = array[i];
cout << "Left: ";
for(i = 0; i < size / 2; i++)
cout << left[i] << ' ';
cout << '\n';
cout << "Right: ";
for(i = 0; i < size - size / 2; i++)
cout << right[i] << ' ';
cout << '\n';
return 0;
}
This code is supposed to split the array into two separate arrays. Somehow the output is wrong when these are the input:
1 2 3 4 5 6 7 8 9 -1
Left: 9 2 3 4
Right: 5 6 7 8 9
After debugging If the elements of left were printed like this:
for(i = size / 2, j = 0; i < size; i++, j++)
{
right[j] = array[i];
cout << left[0] << ' ';
}
cout << '\n';
It says that the value of left[0] is modified after the 5th iteration:
1 1 1 1 9
Left: 9 2 3 4
Right: 5 6 7 8 9
This only happens when the array size is 9. I haven't tested beyond 16 yet. I could fix the code so that it would have the correct size
int right[size - size / 2];
or use malloc() to adhere to the C++ Standard,
int *left = (int *) malloc(sizeof(*left) * n / 2);
int *right = (int *) malloc(sizeof(*left) * n / 2);
so that left wouldn't be affected, but that's not what I'm asking. Why does it only happen when splitting an array size of 9? Why was left[0] overwritten? Is this is a bug in g++ that should be reported or is the problem something else?
It says that the value of left[0] is modified after the 5th iteration:
That is your answer. The problem occurs in the fifth iteration over an array with four elements.
When size is odd, the calculation of size/2 rounds down. So the sum size/2 + size/2 is strictly less than size, yet your loops ensure that all size elements from the original array are assigned somewhere. Something has to be assigned to an unexpected location. We call this "undefined behavior", and whatever the compiler does at that point is correct according to the C++ standard. (Whatever happens, the compiler gets to blame your code for it.) It just happens that when size is 9, the compiler used left[0] as the location for right[4].
Behind the scenes, the left and right arrays are probably more-or-less adjacent in memory. The layout would have right[0] through right[size/2], then possibly some unused space (also known as "padding"), then left[0] through left[size/2]. When you access one-past the last element of right, you end up either in the unused space or in left[0]. When you overwrite the unused space, you see no symptoms since that space is otherwise unused. However, when you overwrite left[0] you definitely see a symptom.
Your compiler apparently uses padding to make sure the arrays are aligned to 4*sizeof(int). (Must be faster that way, as compilers rarely introduce waste without a reason. Still, I am surprised it's not 2*sizeof(int) instead.) That is, there is no padding when size/2 is a multiple of 4. If this guesswork is accurate, you should see this behavior when size is odd and size/2 is a multiple of 4; that is when size is one more than a multiple of 8, as in 9, 17, 25, 33, etc.

Prevent loop from echoing if another same-value array element has been already echoed in C++

First of all, sorry for the mis-worded title. I couldn't imagine a better way to put it.
The problem I'm facing is as follows: In a part of my program, the program counts occurences of different a-zA-Z letters and then tells how many of each letters can be found in an array. The problem, however, is this:
If I have an array that consists of A;A;F;A;D or anything similar, the output will be this:
A - 3
A - 3
F - 1
A - 3
D - 1
But I am required to make it like this:
A - 3
F - 1
D - 1
I could solve the problem easily, however I can't use an additional array to check what values have been already echoed. I know why it happens, but I don't know a way to solve it without using an additional array.
This is the code snippet (the array simply consists of characters, not worthy of adding it to the snippet):
n is the size of array the user is asked to choose at the start of the program (not included in the snippet).
initburts is the current array member ID that is being compared against all other values.
burts is the counter that is being reset after the loop is done checking a letter and moves onto the next one.
do {
for (i = 0; i < n; i++) {
if (array[initburts] == array[i]) {
burts++;
}
}
cout << "\n\n" << array[initburts] << " - " << burts;
initburts++;
burts = 0;
if (initburts == n) {
isDone = true;
}
}
while (isDone == false);
Do your counting first, then loop over your counts printing the results.
std::map<decltype(array[0]), std::size_t> counts;
std::for_each(std::begin(array), std::end(array), [&counts](auto& item){ ++counts[item]; });
std::for_each(std::begin(counts), std::end(counts), [](auto& pair) { std::cout << "\n\n" << pair.first << " - " pair.second; });
for (i = 0; i < n; i++)
{
// first check if we printed this character already;
// this is the case if the same character occurred
// before the current one:
bool isNew = true;
for (j = 0; j < i; j++)
{
// you find out yourself, do you?
// do not forget to break the loop
// in case of having detected an equal value!
}
if(isNew)
{
// well, now we can count...
unsigned int count = 1;
for(int j = i + 1; j < n; ++j)
count += array[j] == array[i];
// appropriate output...
}
}
That would do the trick and retains the array as is, however is an O(n²) algorithm. More efficient (O(n*log(n))) is sorting the array in advance, then you can just iterate over the array once. Of course, original array sequence gets lost then:
std::sort(array, array + arrayLength);
auto start = array;
for(auto current = array + 1; current != array + arrayLength; ++current)
{
if(*current != *start)
{
auto char = *start;
auto count = current - start;
// output char and count appropriately
}
}
// now we yet lack the final character:
auto char = *start;
auto count = array + arrayLength - start;
// output char and count appropriately
Pointer arithmetic... Quite likely that your teacher gets suspicious if you just copy this code, but it should give you the necessary hints to make up your own variant (use indices instead of pointers...).
I would do it this way.
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
string s;
vector<int> capCount(26, 0), smallCount(26, 0);
cout << "Enter the string\n";
cin >> s;
for(int i = 0; i < s.length(); ++i)
{
char c = s.at(i);
if(c >= 'A' && c <= 'Z')
++capCount[(int)c - 65];
if(c >= 'a' && c <= 'z')
++smallCount[(int)c - 97];
}
for(int i = 0; i < 26; ++i)
{
if(capCount[i] > 0)
cout << (char) (i + 65) << ": " << capCount[i] << endl;
if(smallCount[i] > 0)
cout << (char) (i + 97) << ": " << smallCount[i] << endl;
}
}
Note: I have differentiated lower and upper case characters.
Here's is the sample output:
output

Using vector from other class as reverse iterator

I'm on thin ice here, Sorry. I have not used reverse iterators before, and like you can see in my code is that I also want to use a vector from another class as THE iterator object:
double indicators::sRSItemp(input* Close1, int StartDay) {
int n = 14;
double rs;
double rsi;
double tmpavl;
double tmpavg;
if (!RSI.empty()) {
for ( vector<double>::reverse_iterator i = Close1->Close.rbegin(); i != Close1->Close.rend(); ++i ) {
if (Close1->Close[i] < Close1->Close[(i + 1)]){
tmpavl = ((AVL[0] * 13 ) + (Close1->Close[(i +1)] - Close1->Close[i] ) / n);
cout << "AVLtmp " << AVL[0] << endl;
cout << "tmpavl " << tmpavl << endl;
AVL.insert(AVL.begin(), tmpavl);
cout << "AVL is " << AVL[0] << endl;
tmpavg = ((AVG[0] * 13 ) / n );
AVG.insert(AVG.begin(), tmpavg);
// cout << "AVG is " << AVG[i] << endl;
}
else if (Close1->Close[i] > Close1->Close[(i + 1)]) {
tmpavg = ((AVG[0] * 13 ) + (Close1->Close[i] - Close1->Close[(i +1)]) / n );
AVG.insert(AVG.begin(), tmpavg);
// cout << "AVG is " << AVG[i] << endl;
tmpavl = ((AVL[0] * 13 ) / n );
AVL.insert(AVL.begin(), tmpavl);
// cout << "AVL is " << AVL[i] << endl;
}
rs = AVG[0] / AVL[0];
rsi = (100.0 - (100.0 / (1.0 + rs)));
RSI.insert(RSI.begin(), rsi);
}
}
return 0;
}
But when I compile this code I get several errors like this :
error: no match for ‘operator[]’ (operand types are ‘std::vector’ and ‘std::vector::reverse_iterator {aka std::reverse_iterator<__gnu_cxx::__normal_iterator > >}’),
pointing to my vector indexing ??
if (Close1->Close[i] < Close1->Close[(i + 1)]){
Like I said this is new territory for me, and the fault I guess lies with the declaration of the iterator ?
When I iterate through the same vector (front-to-back) in other code there are no problems.
Help much appreciated!
The square brackets operator of std::vector accepts indexes, not iterators.
Here you're trying to use iterators as indexes:
if (Close1->Close[i] < Close1->Close[(i + 1)]) {
Instead of passing iterators to operator [], you should just use asterisks to dereference them, in order to get to vector elements they are pointing to:
if (*i < *(i + 1)) {
Also, be careful with dereferencing i + 1: on the last iteration of your loop i + 1 will be equal to rend() (the reverse past-the-last element iterator). Attempting to access anything via such an iterator will result in undefined behavior.
To see what you're doing wrong, notice that these two are equivalent
int main(){
vector<int> myVec {{1,2,3,4}};
//read then print each value in vector
for(vector<int>::iterator i=myVec.begin();i!=myVec.end(); ++i){
//here i is an iterator not an index
int val = *i; //get value in current position within vector
cout<<val<<endl;
}
for(int i=0; i!=myVec.size(); ++i){
// here i is an index
int val = myVec[i];//get value in current position within vector
cout<<val<<endl;
}
}
in your case use "*i" instead of "Close1->Close[i]" to read the value

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

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) << ", ";

My code is trying to finding all prime numbers between 0 - nth number, what is the use of '+ 1' within the statement 'bool prime[n + 1];'?

I'm new to C++ and is trying to solve the beginner's problem of finding all prime numbers between 0 - nth number. I saw this code online and it works perfectly.
However, my question is what is the use of '+ 1' within the statement 'bool prime[n + 1];'? I have deleted it from the code and everything seems to work just fine. Is it necessary or is it redundant?
void SieveOfEratosthenes(int n) {
bool prime[n + 1];
memset(prime, true, sizeof (prime));
for (int p = 2; p * p <= n; p++) {
// If prime[p] is not changed, then it is a prime
if (prime[p] == true) {
// Update all multiples of p
for (int i = p * 2; i <= n; i += p)
prime[i] = false;
}
}
// Print all prime numbers
for (int p = 2; p <= n; p++)
if (prime[p])
cout << p << endl;
}
int main() {
int n = 1000;
cout << "Following are the prime numbers smaller "
<< " than or equal to " << n << endl;
SieveOfEratosthenes(n);
return 0;
}
In C++ an array of size N have index start from 0 to N-1. so for your problem, for N index assign N+1 size array. so that define the primality to N number.
In C++ (and many other languages) an array of size n has an index for 0 to (n - 1). In this case, you will need to check each number, up to and including n. You therefore need a spot in the array for n, at index prime[n]. This index will only exist if you oversize the array by 1. Otherwise, the array will stop at prime[n - 1].
The reason this works even if you take out the - 1 is that C++ is not fussy about array bounds - once you have an array you can legally read or write at any index, whether or not that index is safe. Notice I said legally, not safely - this is potentially very dangerous behaviour.