Reputation: 960
I have a function that gets an index value, puts it in an array. Then generates a new new random index using rand + srand(key). And it checks if the newly generated index is in array already, it will will keep on generating new index and checking until a unique value is generated.
The problem is that it works fine for small keys, but at longer keys it gets stuck in an infinite loop and can never find a unique value. Here's my code:
int getNewIndex(PPM *im, int index, int *visitedPixels, int *visitedPixelsIndex) {
int i = 0;
if(*visitedPixelsIndex == im->height) {
perror("Cannot encode anymore: pixels limit reached");
exit(1);
}
visitedPixels[*visitedPixelsIndex] = index;
(*visitedPixelsIndex)++;
// If index is already in the list, generate a new number and check again.
while (i < *visitedPixelsIndex) {
if(index == visitedPixels[i]) {
index = rand() % im->height;
i = 0;
} else {
i++;
}
}
return index;
}
EDIT: im->height
which is the image height is about 400-600 in average.
Upvotes: 0
Views: 104
Reputation: 44274
As far as I can see the code will generate an infinite loop when you insert the last free index into the array.
Assume that:
1) im->height
is 500 so that valid index is in the range [0 .. 499]
2) You have already inserted 499 values, i.e. *visitedPixelsIndex
is 499
So when the function is called this condition *visitedPixelsIndex == im->height
will be false so you don't exit but continue on and you insert value number 500 in the array.
Then you do (*visitedPixelsIndex)++;
so that *visitedPixelsIndex
becomes 500.
After that you enter the while
loop trying to find a new unused index
. However - since you have already used all 500 valid index values, you'll never find an unused index.
In other words - an infinite loop
Maybe you should do:
(*visitedPixelsIndex)++;
if(*visitedPixelsIndex == im->height) {
perror("Cannot encode anymore: pixels limit reached");
exit(1);
}
I also think you should generate a new index
before the while
loop.
However, in general I think your code would be more clear if you split the current function into two functions. Like
int isPresent(int index, int *visitedPixels, int N)
{
for(int i = 0; i<N; ++i)
{
if (index == visitedPixels[i]) return 1;
}
return 0;
}
int getNewIndex(PPM *im, int index, int *visitedPixels, int *visitedPixelsIndex)
{
visitedPixels[*visitedPixelsIndex] = index;
(*visitedPixelsIndex)++;
if (*visitedPixelsIndex == im->height) {
perror("Cannot encode anymore: pixels limit reached");
exit(1);
}
do
{
index = rand() % im->height;
} while(isPresent(index, visitedPixels, *visitedPixelsIndex));
return index;
}
Upvotes: 1