c++ : unsequenced modification and access to "i" - c++

My ideas were quite simple.
I wish to copy element by element from vector temp to vector data.
void copy(vector<int> &data, vector<int> &temp)
{
int i=0;
while (i<data.size()) {
data[i]=temp[i++];//unsequenced modification and access to "i"
cout<<i<<endl;
}
Outputs:
temp={1,2,3,4}
but data={1,1,2,3}
even if i's cout values are 1,2,3,4
wonder why.
Thanks for help in advance!

The line
data[i]=temp[i++];//unsequenced modification and access to "i"
has undefined behavior. The result of executing the line will be different depending on whether data[i] is evaluated first or temp[i++] is evaluated first.
Use
while (i<data.size()) {
data[i]=temp[i];
++i;
}
As an alternative, use the std::copy function.
void copy(vector<int> &data, vector<int> &temp)
{
std::copy(temp.begin(), temp.end(), data.begin());
}

One might wonder why the behavior in a case like this isn't defined to be equivalent to incrementing in a separate statement following the one in question. I imagine the reason is that processors have some ability to do post increment for you (see the lodsw family of instructions). When using those instructions, the post increment must occur at the time you fetch the data. So to guarantee the post increment followed all other uses of the incremented variable would require that that fetch be done last, or at least after all other uses of the rsi in that statement. The designers probably decided that was too constraining.

Why people says about undefined behavior?
data[i]=temp[i++];
In this case, first, we will take value from temp[I] (example: y), then "i" will be incremented by 1 (i++), and after that, value from temp[i] (y in our case) will be stored in data[i], where "i" is already incremented by 1.

Related

Heap Buffer Overflow occurs randomly....... for a simple code?(I'm new to C++)

ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000114 at pc 0x000000406d27 bp 0x7ffc88f07560 sp 0x7ffc88f07558
READ of size 4 at 0x602000000114 thread T0
LeetCode No.1
I get this when I give this code
The code below works for some other inputs, but for [3,2,4]\n6, it shows the above error.
vector<int> twoSum(vector<int>& nums, int target) {
int first = 0,last = nums.size() - 1;
vector<int> ref = nums;
while(first < last){
if(ref[first]+ref[last] > target) last--;
else if(ref[first]+ref[last] < target) first++;
else break;
}
vector<int> result;
for(int i=0;i<nums.size();i++){
if(ref[first]==nums[i]) result.push_back(i);
else if(ref[last]==nums[i]) result.push_back(i);
}
if(result[0] > result[1])
swap(result[0],result[1]);
return result;
}
The expected output is [1,2], indexes of values in the array adding up to the value 6.
Consider this while loop.
while(first < last){
if(ref[first]+ref[last] > target) last--;
else if(ref[first]+ref[last] < target) first++;
else break;
}
It seems that the intent was to break and exit when the sum is exactly equal to the target number. However, it is not guaranteed that this will become true. You can also exit the loop when the while condition fails, which happens whenever you reach first == last without yet finding any exact match. That actually happens in the particular case you mention. Follow the logic through and you will find this yourself. The search process misses the desired answer. The logic will not find [1,2]. It will first consider [0,2] and when that fails as too big, it will permanently decrement last and never again consider any combination that involves position 2.
(Likewise, if it fails for being too small it would increment the first position and never again consider combinations with the first value. So there are other failure cases that would happen similarly with that scenario.)
Since you exit without finding the matching combination and first == last, only one number will be pushed into the results. Therefore, when you just assume there are two numbers (false), things blow up as you try to reference the second result number.
General Observation:
You need to plan for the case where no exact match is found and code with that possibility in mind. In that case, what would a correct return result look like to signify no solution was found?
Plus, you could think about how the algorithm could be better at not missing a solution when it is actually present. However, that doesn't change the first requirement. If the target cannot be matched by any sum, you need to be ready for that possibility.
Side Notes:
Rather than repeat the sum of two in if statements, when the sum isn't changing I would suggest that you could create and use an auto local variable once that is
auto sum(ref[first]+ref[last]);
If you want to ensure that argument vector nums is not changed, and communicate that clearly to anyone looking at the declaration of the function, a better choice would be the pass it as a const reference, e.g.
(const vector<int>& nums, ...)
Why does the code create a local copy called ref of the argument vector nums? What is the point of making the effort to make the copy?
Regarding...
last = nums.size() - 1
...notice that if the vector passed in is empty, the value of last goes negative. That might not cause a problem for some code, but it has a dangerous smell in that it looks like code that is just assuming that the vector passed in would never be empty. Practice defensive coding that can be seen to guard against the possibility of unusual input values.
p.s. Part of what saves that last initialization from being broken is the use of int. Since size() returns size_t (unsigned), a common problem is to handle it as unsigned size_t. Then instead of going negative, the result wraps around to the maximum value and the looping may try to work with that as if that was a valid position in the vector. It's hazardous to get into habits that invite those kinds of bugs.

Is it the correct way to use for loop in C++?

I seen weird for loop syntax in C++. Please see following program.
#include <iostream>
using namespace std;
int main()
{
int num, count = 0;
int array[]= {1,1,2,3,4,1,3,2,9,8,7};
cout<<"Which number would you like to know about how many times it appeared?"<<endl;
cin>>num;
for (int i:array)
{
if (i == num)
++count;
}
cout<<"Number "<<num<<" appeared "<<count<<" times in the array"<<endl;
return 0;
}
It is successfully run on GCC Linux platform.
Reference link Here.
So, My question is, Is it the correct way to use for loop in C++?
Also, Is for (int i:array) equivalent to for ( int i:array ; ; )?
Sorry for my poor english. Thanks in advance.
There are now (since C++11) two distinct syntaxes for for-loops, the old C-style:
for (initialization; test; increment)
and the new
for (declaration: container)
In the new syntax, the declaration declares a variable which is successively given the value of each element of the container. Common values of "declaration" are auto val, const auto val, auto& val, and const auto& val, depending on whether you want a reference to the value in the container or a copy, and whether you want the value constant or not.
Both syntaxes are correct. It rather depends what you want to do in the loop. My preference is to use the range based for unless I am going to need the loop counter or iterator ... in which case I fall back on the old style for.
See http://en.cppreference.com/w/cpp/language/range-for for the gory details of the specification (and what is meant by "container").
The syntax for (int i:array) iterates through each element in the array, compared to for (int i = 0; i<sizeof(array); i++) which creates a counter that automatically increments on each iteration of the loop. The counter can then be used to access elements of the array with array[i]
As for which one you'd use, it depends on what you want to do. In your example there isn't a need to keep track of which iteration of the loop you are on, so the former will work fine. If you wanted to, say, print the iteration number each time then you would use the latter.
P.S. your English is perfect :)

Increment operator inside array

I have a C program which does queue operations using an array. In that program, they increment a variable inside array. I can't understand how that works. So, please explain these operations:
array[++i];
array[i++];
Please explain these operations.
array[++i]; - first increments i, then gives you element at the incremented index
equivalent to:
++i; // or i++
array[i];
array[i++]; - also first increments i, but postfix operator++ returns i's value before the incrementation
equivalent to:
array[i];
++i; // or i++
They increment a variable inside array.
No, they don't. You could say they increment i within the call to array subscript operator.
The ++i increments i before evaluating it.
The i++ inrements i after evaluating it.
If i=1 then array[++i] sets i=2 and then fetches array[2].
If i=1 then array[i++] fetches array[1] then sets i=2.
The post- and pre- operations happen after or before the expression they are involved in is evaluation.
I generally discourage the use of post and pre increment operators in expressions. They can lead to confusion at best and bugs at worst.
Consider what x = array[++i] + array[i--] ; should be. See how easy it is to confuse the programmer ( or the poor devil who has to fix your code ? :-) ).
Post and pre increment and decrement operations can also produce problems in macros, as you end up with the potential for an operation to be duplicated multiple times, especially with macros.
It is simpler and produces easier to maintain code to avoid post and pre increments in expressions, IMO.
So, you know i++ and ++i increment i with 1. Also, this instruction returns i, so you can put this somewhere in your code where you need the value of i.
The difference between the 2 is that i++ is post increment, and ++i is pre increment. What does this mean?
Well, let's say i is 6. When you do:
array[i++]
array[i]
You will actually be doing:
array[6]
array[7]
Because you use post increment: first return value, then increment i.
If you do:
array[++i]
array[i]
You'll basically be doing:
array[7]
array[7]
Because you use pre increment: first increment i, then return its value.
Now try to find what your code does ;-)
Hope this helps.
array[++i]; - increments the value of i and then uses the incremented value as an index into array
array[i++]; -indexes into the array and then increments the value of i
I know your question was in the context of a queue, but I'm going to use a stack for illustration.
Imagine an array-based stack:
T stack[N]; // for some type T
size_t sp = N; // stack pointer
In this example, the stack grows "downwards", where index N-1 is the bottom of the stack and index 0 is the top.
A push operation looks like the following:
stack[--sp] = val;
--sp evaluates to sp - 1, and as a side effect decrements the value in sp, so the above statement is equivalent to writing
stack[sp - 1] = val;
sp = sp - 1;
with the caveat that sp may be updated before the assignment is complete.
A pop operation looks like this:
val = stack[sp++];
sp++ evaluates the the current value of sp, and as a side effect increments the value in sp, so it's equivalent to writing
val = stack[sp];
sp = sp + 1;
with the same caveat as above.

Simple For Loop C++ why

I am just wondering why I would do this in c++
for(int i=0, n=something.size(); i<n; ++i)
vs
for(int i=0; i<something.size(); ++i)
..
Assuming syntactically correct versions of both samples, if the call to something.size() were expensive, the first sample would potentially be more efficient because it saves one call per loop iteration. Even so, you should measure whether it actually makes a difference.
Note that the two would have different semantics if the size of something were to change inside of the loop.
The loop condition is evaluated before every loop round, so if the operand of the comparison doesn't change (i.e. you don't mutate the sequence during its iteration), then you don't need to recompute the operand each time and instead hoist it out.
Whether that makes a difference depends on how much the compiler can see of the size() call. For instance, if it can prove that the result cannot change during the iteration, then it may already do the hoisting for you. If in doubt, compile both versions and compare the machine code.
If you do
for(int i=0; i<something.size(); ++i);
it will be correct.
You should check in some C++ handbook how for loop looks like.
Your second example is invalid C++ code
The two examples are not the same.
for(int i=0, n=something.size(); i<n; ++i)
{
// ....
}
evaluates something.size() only once.
for(int i=0; i<something.size(); ++i) // Syntax corrected
{
// ....
}
evaluates something.size() in each loop.
So they could behave very differently if something.size() changed while doing the loop.
If you know something.size() will not change, you should go for the first solution for performance reason (i.e. only one call to something.size()).
If something.size() can change (e.g. in the body of the for-loop) the second option is the way to go.

Incrementing in C++ - When to use x++ or ++x?

I'm currently learning C++ and I've learned about the incrementation a while ago.
I know that you can use "++x" to make the incrementation before and "x++" to do it after.
Still, I really don't know when to use either of the two... I've never really used "++x" and things always worked fine so far - so, when should I use it?
Example: In a for loop, when is it preferable to use "++x"?
Also, could someone explain exactly how the different incrementations (or decrementations) work? I would really appreciate it.
It's not a question of preference, but of logic.
x++ increments the value of variable x after processing the current statement.
++x increments the value of variable x before processing the current statement.
So just decide on the logic you write.
x += ++i will increment i and add i+1 to x.
x += i++ will add i to x, then increment i.
Scott Meyers tells you to prefer prefix except on those occasions where logic would dictate that postfix is appropriate.
"More Effective C++" item #6 - that's sufficient authority for me.
For those who don't own the book, here are the pertinent quotes. From page 32:
From your days as a C programmer, you may recall that the prefix form of the increment operator is sometimes called "increment and fetch", while the postfix form is often known as "fetch and increment." The two phrases are important to remember, because they all but act as formal specifications...
And on page 34:
If you're the kind who worries about efficiency, you probably broke into a sweat when you first saw the postfix increment function. That function has to create a temporary object for its return value and the implementation above also creates an explicit temporary object that has to be constructed and destructed. The prefix increment function has no such temporaries...
From cppreference when incrementing iterators:
You should prefer pre-increment
operator (++iter) to post-increment
operator (iter++) if you are not going
to use the old value. Post-increment
is generally implemented as follows:
Iter operator++(int) {
Iter tmp(*this); // store the old value in a temporary object
++*this; // call pre-increment
return tmp; // return the old value }
Obviously, it's less efficient than
pre-increment.
Pre-increment does not generate the temporary object. This can make a significant difference if your object is expensive to create.
I just want to notice that the geneated code is offen the same if you use pre/post incrementation where the semantic (of pre/post) doesn't matter.
example:
pre.cpp:
#include <iostream>
int main()
{
int i = 13;
i++;
for (; i < 42; i++)
{
std::cout << i << std::endl;
}
}
post.cpp:
#include <iostream>
int main()
{
int i = 13;
++i;
for (; i < 42; ++i)
{
std::cout << i << std::endl;
}
}
_
$> g++ -S pre.cpp
$> g++ -S post.cpp
$> diff pre.s post.s
1c1
< .file "pre.cpp"
---
> .file "post.cpp"
The most important thing to keep in mind, imo, is that x++ needs to return the value before the increment actually took place -- therefore, it has to make a temporary copy of the object (pre increment). This is less effecient than ++x, which is incremented in-place and returned.
Another thing worth mentioning, though, is that most compilers will be able to optimize such unnecessary things away when possible, for instance both options will lead to same code here:
for (int i(0);i<10;++i)
for (int i(0);i<10;i++)
I agree with #BeowulfOF, though for clarity I would always advocate splitting the statements so that the logic is absolutely clear, i.e.:
i++;
x += i;
or
x += i;
i++;
So my answer is if you write clear code then this should rarely matter (and if it matters then your code is probably not clear enough).
If count{5};
If you use ++count it will be process beforethe statement
total = --count +6;
Total will be equal to 10
If you use count++ it will be process after the statement
total = count-- +6;
Total will be equal to 11
Just wanted to re-emphasize that ++x is expected to be faster than x++, (especially if x is an object of some arbitrary type), so unless required for logical reasons, ++x should be used.
Postfix form of ++,-- operator follows the rule use-then-change ,
Prefix form (++x,--x) follows the rule change-then-use.
Example 1:
When multiple values are cascaded with << using cout then calculations(if any) take place from right-to-left but printing takes place from left-to-right e.g., (if val if initially 10)
cout<< ++val<<" "<< val++<<" "<< val;
will result into
12 10 10
Example 2:
In Turbo C++, if multiple occurrences of ++ or (in any form) are found in an expression, then firstly all prefix forms are computed then expression is evaluated and finally postfix forms are computed e.g.,
int a=10,b;
b=a++ + ++a + ++a + a;
cout<<b<<a<<endl;
It's output in Turbo C++ will be
48 13
Whereas it's output in modern day compiler will be (because they follow the rules strictly)
45 13
Note: Multiple use of increment/decrement operators on same variable
in one expression is not recommended. The handling/results of such
expressions vary from compiler to compiler.
You explained the difference correctly. It just depends on if you want x to increment before every run through a loop, or after that. It depends on your program logic, what is appropriate.
An important difference when dealing with STL-Iterators (which also implement these operators) is, that it++ creates a copy of the object the iterator points to, then increments, and then returns the copy. ++it on the other hand does the increment first and then returns a reference to the object the iterator now points to. This is mostly just relevant when every bit of performance counts or when you implement your own STL-iterator.
Edit: fixed the mixup of prefix and suffix notation
You asked for an example:
This (order is a std::vector) will crash for i == order.size()-1 on the order[i].size() access:
while(i++ < order.size() && order[i].size() > currLvl);
This will not crash at order[i].size(), as i will be incremented, checked and the loop will be exited:
while(++i < order.size() && order[i].size() > currLvl);
Understanding the language syntax is important when considering clarity of code. Consider copying a character string, for example with post-increment:
char a[256] = "Hello world!";
char b[256];
int i = 0;
do {
b[i] = a[i];
} while (a[i++]);
We want the loop to execute through encountering the zero character (which tests false) at the end of the string. That requires testing the value pre-increment and also incrementing the index. But not necessarily in that order - a way to code this with the pre-increment would be:
int i = -1;
do {
++i;
b[i] = a[i];
} while (a[i]);
It is a matter of taste which is clearer and if the machine has a handfull of registers both should have identical execution time, even if a[i] is a function that is expensive or has side-effects. A significant difference might be the exit value of the index.