do/while doesn't check condition

V

voger

Hi everyone

Can anyone please explain this strange behavior?

I have this function that is supposed to copy the contents of one array to
one other array, but sorted. I don't know if the logic is correct but when
I try to debug this the do/while loop results in an endless loop. The Two
first values of the unsorted array are

unsorted[0] = 8
unsorted[1] = 9

I tried to step over it with a debugger. When it reaches to the do/while
loop it checks the if statement which results to false, checks the else if
statement which results to true, sets larger to true, DOESN'T check the
while statement at all and goes back to the if statement. Where is the
mistake?

void sort(int sorted[], int unsorted[])
{

bool larger = false;
//first number is just copied
sorted[0] = unsorted[0];

// start sorting
for(int i = 1; i<10; i++)
{
// first copy the value to the sorted array
sorted = unsorted;


// then start comparing
int j = i;

do
{
// if less than previous then swap
if(sorted[j] < sorted[j -1])
{
int temp = sorted[j -1];
sorted[j -1] = sorted[j];
sorted[j] = temp;
j--;
larger = false;
}

// else do nothing
else if(sorted[j] >= sorted[j -1])
{
larger = true;
}
}while(j != 0 || !larger);

}
}
 
V

Victor Bazarov

voger said:
Can anyone please explain this strange behavior?

I have this function that is supposed to copy the contents of one
array to one other array, but sorted. I don't know if the logic is
correct but when I try to debug this the do/while loop results in an
endless loop. The Two first values of the unsorted array are

unsorted[0] = 8
unsorted[1] = 9

I tried to step over it with a debugger. When it reaches to the
do/while loop it checks the if statement which results to false,
checks the else if statement which results to true, sets larger to
true, DOESN'T check the while statement at all and goes back to the
if statement. Where is the mistake?

void sort(int sorted[], int unsorted[])
{

bool larger = false;
//first number is just copied
sorted[0] = unsorted[0];

// start sorting
for(int i = 1; i<10; i++)

10? Why not pass the value in?
{
// first copy the value to the sorted array
sorted = unsorted;


// then start comparing
int j = i;

do
{
// if less than previous then swap
if(sorted[j] < sorted[j -1])
{
int temp = sorted[j -1];
sorted[j -1] = sorted[j];
sorted[j] = temp;


Prefer calling 'std::swap' for this.
j--;
larger = false;
}

// else do nothing
else if(sorted[j] >= sorted[j -1])
{
larger = true;
}
}while(j != 0 || !larger);

What are you checking, exactly? It should probably be

(j > 0 && !larger)

(too lazy to check).

V
 
M

Mumia W.

Hi everyone

Can anyone please explain this strange behavior?

I have this function that is supposed to copy the contents of one array to
one other array, but sorted. I don't know if the logic is correct but when
I try to debug this the do/while loop results in an endless loop. The Two
first values of the unsorted array are

unsorted[0] = 8
unsorted[1] = 9

I tried to step over it with a debugger. When it reaches to the do/while
loop it checks the if statement which results to false, checks the else if
statement which results to true, sets larger to true, DOESN'T check the
while statement at all and goes back to the if statement. Where is the
mistake?

void sort(int sorted[], int unsorted[])
{

bool larger = false;
//first number is just copied
sorted[0] = unsorted[0];

// start sorting
for(int i = 1; i<10; i++)
{
// first copy the value to the sorted array
sorted = unsorted;


// then start comparing
int j = i;

do
{
// if less than previous then swap
if(sorted[j] < sorted[j -1])
{
int temp = sorted[j -1];
sorted[j -1] = sorted[j];
sorted[j] = temp;
j--;
larger = false;
}

// else do nothing
else if(sorted[j] >= sorted[j -1])
{
larger = true;
}
}while(j != 0 || !larger);

}
}


Most likely this relates to optimization. Disable it to get normal
execution paths.

Your program goes into an infinite loop, and that's probably what you're
trying to debug. With cgdb I can see that some of the tests are skipped
when optimizations are enabled in gcc.
 
S

Serge Skorokhodov

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7 (MingW32)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGLyZzNv/GlQebDOMRAizLAJ965cETtfV8PAJBzxw24Z0Oat8bvACgnv8I
sGWTDR+FEk0YF7U29gvTdNU=
=3lRp
-----END PGP SIGNATURE-----
 
V

voger

Serge said:
unsorted[0] =3D 8=20
unsorted[1] =3D 9

bool larger =3D false;
//first number is just copied
sorted[0] =3D unsorted[0];
=20
// start sorting
for(int i =3D 1; i<10; i++)
{
// first copy the value to the sorted array
sorted =3D unsorted;
=20
=20
// then start comparing
int j =3D i;
=20
do
{
// if less than previous then swap
if(sorted[j] < sorted[j -1])
{
int temp =3D sorted[j -1];
sorted[j -1] =3D sorted[j];
sorted[j] =3D temp;
j--;
larger =3D false;
}
=20
// else do nothing
else if(sorted[j] >=3D sorted[j -1])
{
larger =3D true;
}
}while(j !=3D 0 || !larger);



Without talking about details, while(j !=3D 0 || !larger is always true i=
n
this situation. What you probably intended was:
while ( j !=3D 0 && !larger )
The latter breaks the iteration when j reaches zero OR when larger is tru=
e.

BTW, the same algo can be written in slightly mor C style;)

// then start comparing
int j =3D i;
do
{
if ( sorted[j] >=3D sorted[j-1] )
{
// stop iterating, no need for special flag
break;
}
// if less than previous then swap
else if ( sorted[j] < sorted[j-1] )
{
int temp =3D sorted[j-1];
sorted[j-1] =3D sorted[j];
sorted[j] =3D temp;
--j;
}
} while ( j > 0 );
// the condition checks if it is safe for iterate
// rather than if the array is sorted or not
// (checked inside the do...while operator).

--=20
Serge



Thank you. I was experimenting 2+ hours for that line and didn't get it
right. Now it is working perfectly :D.

As for the debugger not checking condition thing, now I believe that it (the
debugger) considers the do and the while line as one. So the graphical part
doesn't step through the while line but through the do line. The same
result but very confusing to the newbie.

Thanks again :D
 
O

Old Wolf

Hi everyone

Can anyone please explain this strange behavior?

I have this function that is supposed to copy the contents of one array to
one other array, but sorted. I don't know if the logic is correct but when
I try to debug this the do/while loop results in an endless loop.
do
{
// if less than previous then swap
if(sorted[j] < sorted[j -1])
{
int temp = sorted[j -1];
sorted[j -1] = sorted[j];
sorted[j] = temp;
j--;
larger = false;
}

// else do nothing
else if(sorted[j] >= sorted[j -1])
{
larger = true;
}
}while(j != 0 || !larger);

Well, it is never possible to not trigger the end condition.

If the first block is selected, then 'larger' is false so the loop
continues. If the second block is selected then j can't have
been zero, so the loop continues. If neither block is selected
then 'j' and 'larger' have the same values as they had on the
previous iteration, which continued, so the current one must
also continue.

Try writing your logic out as a flow-chart first, and then check
if your code corresponds to it or not.
 
J

James Kanze

<skip>
BTW, the same algo can be written in slightly mor C style;)
// then start comparing
int j = i;
do
{
if ( sorted[j] >= sorted[j-1] )
{
// stop iterating, no need for special flag
break;
}
// if less than previous then swap
else if ( sorted[j] < sorted[j-1] )
{
int temp = sorted[j-1];
sorted[j-1] = sorted[j];
sorted[j] = temp;
--j;
}
} while ( j > 0 );

Well, most places I've worked have banned using break to leave a
loop, because it rapidly makes the code unreadable. But in this
case, what's wrong with:

while ( j > 0 && sorted[ j ] < sorted[ j - 1 ] ) {
std::swap( sorted[ j ], sorted[ j - 1 ] ) ;
-- j ;
}

That's what I'd write, anyway.
 
M

Miguel Gimenez

Old said:
Hi everyone

Can anyone please explain this strange behavior?

I have this function that is supposed to copy the contents of one array to
one other array, but sorted. I don't know if the logic is correct but when
I try to debug this the do/while loop results in an endless loop.
do
{
// if less than previous then swap
if(sorted[j] < sorted[j -1])
{
int temp = sorted[j -1];
sorted[j -1] = sorted[j];
sorted[j] = temp;
j--;
larger = false;
}

// else do nothing
else if(sorted[j] >= sorted[j -1])
{
larger = true;
}
}while(j != 0 || !larger);

Well, it is never possible to not trigger the end condition.

If the first block is selected, then 'larger' is false so the loop
continues. If the second block is selected then j can't have
been zero, so the loop continues. If neither block is selected
then 'j' and 'larger' have the same values as they had on the
previous iteration, which continued, so the current one must
also continue.

One of the two blocks will always execute, as they have inverted
conditions. The OP should remove the if after the else.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,008
Latest member
HaroldDark

Latest Threads

Top