I'm currently developping a vision system which is controlled/moonitored via a computer application that I'm writting in C/C++. If you are wondering why I,m writting in C/C++ its basically that my vision sensor (LMI Gocator 2490) has functions developped in C and that I'm using opencv (C++) to analyse its data. Long story short, I've had 1 informatics course which was in C and I'm bad at C++.
I'm wondering if there is a simple way, using or writting a function for example, to retrieve an array index that loops back to its begining instead of trying to read write in an index that isn't part of the array which also causes mem access violation. For example:
long a[4];
for (size_t i = 0; i < sizeof(a) / sizeof(long); i++)
{
if (a[i] && a[i + 1]) //Define some conditions regarding a[i] and a[i+1]
{
//Process code
}
}
So here, its easy to understand that when i will reach the value of 3, I will get mem access violation. What I would like to do, is to have some sort of mecanism which would return a array index that "looped" back to begining. In the case shown above, i+1 where i = 3 would be 0. If I were to put i+2, I would like to get 1, and so on...
This might be silly but it would save me the pain of writting 4 times the same logic in some switch/case statement inside a for-loop which then I'd need to apply modifications in all the 4 logics when debugging... Thank's!
use modulus to wrap when reaching the upper bound
long a[4];
size_t sz = sizeof(a) / sizeof(long);
for (size_t i = 0; i < sz; i++)
{
if (a[i] && a[(i + 1) % sz]) //Define some conditions regarding a[i] and a[i+1]
{
//Process code
}
}
maybe not super-optimal performance wise, though (well, with a value of 4, the compiler can trade modulus for mask so it would be okay).
In the general case, avoid a division, and check if overruns then choose 0 if it does
for (size_t i = 0; i < sz; i++)
{
size_t j = i < sz-1 ? i+1 : 0;
if (a[i] && a[j]) //Define some conditions regarding a[i] and a[i+1]
{
//Process code
}
}
(the code will work in C and C++)
Related
First at all I'm a complete beginner in C++, that's why I apologize if this question may be stupid (or may not have any sense) but I have absolutely no clues about what can I do in my situation.
So, I've been trying to learn about multi-threading lately because I thought it'd be a way much better to use threads instead of a simple loop running across a whole big content (which is the content of a file) to gain actually more speed.
Here's the code I actually have (not complete but it doesn't matters in this case):
int end = 40000;
std::string content; // this variable is filled before calling the function "another_function", don't mind it
// this function is completely useless, this is just for testing purposes
void dummy_function(int *idx, int value_to_divide) {
std::list<int> test;
for (; *idx <= ending / div; *idx++) {
int count = 100 + *i;
test.insert(test.end(), { 1, 2, 3, count });
std::cout << content.c_str() + *i << endl;
test.clear();
}
}
void another_function() {
int idx = 0;
std::vector<std::thread> th;
for (int j = 4; j != 0; j--) {
th.push_back(std::thread(&dummy_function, &idx + ((j != 4) ? (end / (j + 1)) : 0), j));
}
for (auto& thread:th)
thread.join();
}
How I see what I did is that I divide the reading of the content variable into 4 several threads (to make them stopping at the same time as they should have the same length), the first one starting at 0 (beginning), the 2nd one is starting at (i + (end / 3)),
et cetera...
But, it does segfault when the 1st thread stop and in fact the other threads are not even starting where I thought they would start, so maybe I didn't even understand the concept of threading in first place (as I said I'm a beginner in this lol).
I've heard about something called "Safe Queue" or "Safe Threading" (using mutex and stuff related to) but it seems that I didn't understand how to use it in my case.
Is someone able to explain how I could make these threads running in parallel and "safely" (so)?
Thank you :)
This isn't a threading problem. It's far more basic than that.
Here's your code:
void another_function() {
int idx = 0;
std::vector<std::thread> th;
for (int j = 4; j != 0; j--) {
th.push_back(std::thread(&dummy_function, &idx + ((j != 4) ? (end / (j + 1)) : 0), j));
}
for (auto& thread:th)
thread.join();
}
idx is a single integer on the stack. You're passing the address of idx plus some offset that you're calculating. And then your function assumes that's a good address.
But it's NOT a good address. It points out to who knows what. You don't have 40000 integers allocated anywhere. You have exactly 1.
Now, I'm not sure what else you're trying to do, but you could change idx slightly:
int idx[40000];
And then I wouldn't do the for-loop quite the same. Instead:
for (int j = 4; j != 0; j--) {
int offset = j != 4 ? end / (j + 1) : 0;
th.push_back(std::thread(&dummy_function, &idx[offset], j));
}
Or something like that. I don't think the method you're calling is going to be happy, though, and you would do better to instead pass in the entire array and then a start + length or start + stop values.
But your main problem is because you're running rampant over random memory.
In C and C++, size_t is an unsigned type that is used for expressing size. It expresses intent and somewhat simplifies range assertions (len < upper_bound vs len >= 0 && len < upper_bound for signed integers).
(In all the examples below len means the length of the array a).
The idiom for a for loop is: for (i = 0; i < len; i++). The idiom for a backward for loop is for (i = len-1; i >= 0; i--). But having unsigned loop indices introduces subtle bugs, and every so often I mess up the edge cases.
First, the backwards for loop. This code underflows for len=0.
for (size_t i = len-1; i >= 0; i--) { // Bad: Underflows for len=0
use(a[i]);
}
There's the --> "operator" trick, which looks strange if you're not used to it.
for (size_t i = len; i--> 0;) {
use(a[i]);
}
You can use a signed type for the loop index variable, but that overflows if len > INT_MAX. Many people and organizations considers that risk so minimal that they just stick to int.
for (int i = len-1; i >= 0; i--) { // BAD: overflows for len < INT_MAX
use(a[i]);
}
So I've settled for this construct, since it's closest to the canonical for-loop form and has the simplest expressions.
for (size_t i = len; i > 0; i--) {
size_t pos = i-1;
use(a[pos]);
}
My problem iterating from 0 to len-1
That is, looping over the range [0, len-1). This loop underflows when len=0.
for (size_t i = 0; i < len-1; i++) { // BAD: Underflows for len=0.
use(a[i]);
}
As for the iterating backwards case, you can use signed integers but that may cause overflows.
for (int i = 0; i < len-1; i++) { // BAD: Will overflow if len > INT_MAX
use(a[i]);
}
I tend to add another expression to the loop condition, checking for len > 0, but that feels clumsy.
for (size_t i = 0; len > 0 && i < len-1; i++) {
use(a[i]);
}
I can add an if statement before the loop, but that also feels clumsy.
Is there a less bulky way of writing a for loop with unsigned index variables looping from 0 to len-1?
There are two cases here.
Iterating forward from 0 to len - 2 inclusive
for (size_t i = 0; i + 1 < len; ++i) {
size_t index = i;
// use index here
}
Iterating backward from len - 2 to 0 inclusive
for (size_t i = len; i > 1; --i) {
size_t index = i - 2;
// use index here
}
How about
for (size_t i = 0; i+1 < len; i++) {
use(a[i]);
}
In all these cases, you have one common theme: You have an index that has a start value. It gets incremented or decremented until it reaches the end value, which terminates the loop.
One thing that helps here is to make these two values explicit. In the simplest case, forward-iterating the whole range, the end value is simply len:
for (size_t i=0, end=len; i!=end; ++i) {
///...
}
This follows the general advise given to people using iterators. In particular, pay attention to the comparison, which works here and which is actually required for some iterators.
Now, backward iterating:
for (size_t i=len-1, end=-1; i!=end; --i) {
///...
}
Lastly, iterating a subset excluding the last n elements of the range backwards:
if (len > n) {
for (size_t i=len-n-1, end=-1; i!=end; --i) {
///...
}
}
Actually, what you were fighting with was your attempt to put too much stuff into the loop logic. Just be explicit that this requires more than n elements in order to do anything at all. Yes, you could put len > n into the loop condition, but that wouldn't give you clear and simple code who's intention anyone understands.
I tend to add another expression to the loop condition, checking for
len > 0, but that feels clumsy.
Your code should follow the logic. It is not clumsy at all. And it is much more readable for humans.
As the loop makes no sense if the len == 0 and I usually use the if statement. It makes the code easy to understand and maintain.
if(len)
{
for (size_t i = 0; i < len-1; i++) { /*...*/ }
}
or you can also add the check in the loop. BTW you only check if it is not zero.
for (size_t i = 0; len && i < len-1; i++) { /*...*/ }
There are many possible answers for this question. Which is best is opinion based. I'll offer some options.
For iterating over all elements of an array in reverse order, using an unsigned index, one option is
for (size_t index = 0; index < len; ++index)
{
size_t i = len - 1 - index;
use(a[i]);
}
or (more simply)
for (size_t i = 0; i < len; ++i)
{
use(a[len - 1 - i]);
}
In both cases, if len is zero, the loop body is not executed. Although the loops increment rather than decrement, both access elements in reverse order. If you are frequently writing such loops, it is also not difficult to write a little inline function of the form
size_t index_in_reverse(size_t index, size_t len)
{
return len - 1 - index;
}
and do
for (size_t i = 0; i < len; ++i)
{
use(index_in_reverse(i, len));
}
To iterate forward over all elements of the loop in forward order, except the last, I'd make that explicit rather than trying to do it in the loop condition.
if (len > 0)
{
size_t shortened_len = len - 1;
for (size_t i = 0; i < shortened_len; ++i)
use(a[i]);
}
The reason I introduce the variable shortened_len is to make the code self-documenting about the fact it is not iterating over the entire array. I've seen too many cases where a condition of the form i < len - 1 is "corrected" by a subsequent developer to remove the - 1 because they believe it is a typo.
That may feel "clumsy" to the OP, but I suggest that
for (size_t i = 0; len > 0 && i < len-1; i++) {
use(a[i]);
}
is harder for a human to understand (putting multiple tests in a loop condition, forces a person maintaining the code to actually work out what both conditions do and, how they interact). Given a choice between code that is "concise" or code that is "less concise but consumes less brainpower of an unacquainted human to understand" I will ALWAYS choose the latter. Bear in mind that the user maintaining the code six months later may be yourself, and there are few thought processes more humbling than "What idiot wrote this?? Oh, it was me!".
i have a task in which i have to code a program to find a peak element in an array. I did code it, but when i showed it to my teacher she told me it wasn't accurate, even tho it was running fine on Dev C++.She told me to modify it. Can someone tell me, whats wrong with the code and how do i modify it.
int main(){
int arr[50];
cout<<"Enter size:";
int n;
cin>>n;
cout<<"Elements:";
for(int i=0;i<n;i++){
cin>>arr[i];
}
for(int i=0;i<n;i++){
if(arr[i]>arr[i+1] && arr[i]>arr[i-1]){
cout<<"PEAK: "<<arr[i]<<endl;
}
}
return 0;
}
The problem lies within second for loop body.
As NathanOliver pointed out in the comments, the arr[i] > arr[i-1] shall try to access memory at invalid offset when i is equal to 0.
The same goes for the other condition - arr[i] > arr[i+1] would result in access out of bounds - well, your arr can hold a maximum of 50 elements, so if n is lower than 50, you should only access uninitialized memory.
The peak-finding condition could be rewritten as:
for (unsigned i = 0u; i < n; i++){
bool isPeak = true;
if (i > 0 && arr[i] < arr[i - 1]){
isPeak = false;
}
if (i < n - 1 && arr[i] < arr[i + 1]){
isPeak = false;
}
if (isPeak){
std::cout << "PEAK: " << arr[i] << '\n';
}
}
This exploits the short circuiting of logical operators - expressions are evaluated left to right, therefore - if we come back to i > 0 && arr[i] < arr[i - 1] condition - potentially dangerous check (that might result in invalid access) will not take place if the first condition (i > 0) is false.
As for the code itself, it now checks each side of the current element separately.
An ever better thing to do (although probably not related to what your teacher means) would be to use std::vector. The code could then handle more than 50 elements.
I wrote a multiplication table like this:
#include <iostream>
#include <conio.h>
using namespace std;
int main(){
int table[9][9], i, j;
for (i = 0; i < 10; ++i){
for (j = 0; j < 10; ++j)
{
table[i][j] = (i + 1) * (j + 1);
cout << table[i][j] << "\t";
}
cout << endl;
}
_getch();
return 0;
}
And when I run it it gives me the right answer but when I press a key it throws this error:
run time check faliure #2-stack around the variable table was corrupted
But it doesn't throw that error when I change the code to this:
......
int main(){
**int table[10][10]**, i, j;
for (i = 0; i < 10; ++i){
......
If they both give the same answer then what's the difference??
You are overflowing your arrays, The max index in bounds is 8 (since the indices are zero based and you defined 9 cells as your dimensions size so 8 will be the last cell in each dimension) and your for loop can reach till 9 (including 9) which will cause an overflow.
The snippet int table[9] declares an array of size 9, that means valid indices are actually 0-8. But your loop iterates from 0 to 9. This causes a write into an invalid memory region (which doesn't belong to your array), therefore corrupting your stack.
Now you actually have a two dimensional array, but the problem remains the same.
You're going outside the array in your for loops. They should be:
for (i = 0; i < 9; ++i){
for (j = 0; j < 9; ++j)
The array indexes run from 0 to 8, but you were going up to 9 because your conditions were i < 10 and j < 10.
Arrays in C/C++ start with 0 index.
When you declare table[9][9] you reserve memory for 9x9 array with indexes 0..8, 0..8
but in for loop your upper index is 9 - it is out of array range
I guess you should declare table like you pointed:
int table[10][10];
You are accessing out of array's range element.
Your array is a 9x9 table but you are trying to access 10x10 table.
So either use i<9 and j<9 in your both loops or increase your array size to table[10][10].
Hope this might help.
Rule of thumb: in for loops, N in (i = 0; i < N; i++) clause should (almost always) be equal to the corresponding array's length. When you see either i <= N or i < N + 1, it's (most often) a sign of the dreaded off-by-one bug.
I have the following C++ loop:
for (i = LEN_MAX - 1; i >= 0; i--) {
int j = i - LEN_MAX + len;
if (j < 0)
break;
int ind = a.getElem(j);
short t = ind;
ind = --c[ind];
b.setElem(ind, t);
}
What I would like to do is remove all dependency between iterations from it. In the above loop, for example, the line ind = --c[ind] has an inter-iteration dependency, because to decrease, I need to have the value from the previous iteration. Here is an example of the transformation I'm looking for:
From:
for (i = 1; i < RADIX_MAX; i++) {
if (i == radix)
break;
c[i] += c[i - 1];
c[i] += temp;
}
To:
short temp = c[0];
for (i = 1; i < RADIX_MAX; i++) {
if (i == radix)
break;
c[i] += temp; //this loop no longer depends on last iteration
temp = c[i];
}
I want to apply this same technique to the first loop I posted, but I'm not sure how. The reason I want to do this is because it is required in order to optimize the performance of a tool I am using. Anyone have any ideas?
There is no simple transformation of the loop you provided to remove the inter-iteration dependency (And the second example you gave doesn't actually remove the inter-iteration dependency). Each iteration depends on what happened to c the previous iteration and there's just no way around that with the current implementation. If you know something about the algorithm and/or the values stored within c and/or the values within a, you may be able to rework the code to remove the order dependency, we just can't do it given the short segment of code you provided.