Discussion:
byte copy
John de la Garza
2014-10-19 21:32:19 UTC
Permalink
Can anone see why these two pieces of code would behave differently?
They are used in a mergesort merge

the top one ends up with c (cp points to an offset in c)
1 2 3 1

the bottom one (not commented out)
results in 1 2 3 4 (correct)

/*
if (alen == 0)
memcpy(cp, bp, blen);
else if (blen == 0){
memcpy(cp, ap, alen);
}
*/
if (alen == 0)
while (blen--)
*cp++ = *bp++;
else
while (alen--)
*cp++ = *ap++;


if you want to read it with more context see below
---------------------------------------------------

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void pr_array(int *a, int len)
{
int i;
for (i = 0; i < len; i++)
printf("%d ", a[i]);
printf("\n");
}
void merge(int *a, int alen, int *b, int blen, int *c)
{
int *ap = a;
int *bp = b;
int *cp = c;

while (alen && blen) {
if (*ap <= *bp) {
*cp++ = *ap++;
alen--;
} else{
*cp++ = *bp++;
blen--;
}
}
if (alen == 0)
memcpy(cp, bp, blen);
else if (blen == 0){
memcpy(cp, ap, alen);
}
/*
if (alen == 0)
while (blen--)
*cp++ = *bp++;
else
while (alen--)
*cp++ = *ap++;
*/
}

void msort(int *arr, int len)
{
int mid = len / 2;
int llen = mid;
int rlen = len - mid;
int *l = malloc(llen);
int *r = malloc(rlen);
int i;

if (len <= 1)
return;
for (i = 0; i < llen; i++)
l[i] = arr[i];
for (i = mid; i < mid + rlen; i++)
r[i-mid] = arr[i];
msort(l, llen);
msort(r, rlen);
merge(l, llen, r, rlen, arr);
free(l);
free(r);
}
int main()
{
int arr[] = {4,3, 2, 1};
int len = sizeof(arr) /sizeof(int);
int x[] = {1,3,5,7};
int y[] = {2,4,6,8};

msort(arr, len);
pr_array(arr, len);
return(0);
}

--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
John de la Garza
2014-10-19 22:10:27 UTC
Permalink
Post by John de la Garza
Can anone see why these two pieces of code would behave differently?
They are used in a mergesort merge
the top one ends up with c (cp points to an offset in c)
1 2 3 1
the bottom one (not commented out)
results in 1 2 3 4 (correct)
/*
if (alen == 0)
memcpy(cp, bp, blen);
else if (blen == 0){
memcpy(cp, ap, alen);
}
*/
if (alen == 0)
while (blen--)
*cp++ = *bp++;
else
while (alen--)
*cp++ = *ap++;
if you want to read it with more context see below
---------------------------------------------------
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void pr_array(int *a, int len)
{
int i;
for (i = 0; i < len; i++)
printf("%d ", a[i]);
printf("\n");
}
void merge(int *a, int alen, int *b, int blen, int *c)
{
int *ap = a;
int *bp = b;
int *cp = c;
while (alen && blen) {
if (*ap <= *bp) {
*cp++ = *ap++;
alen--;
} else{
*cp++ = *bp++;
blen--;
}
}
if (alen == 0)
memcpy(cp, bp, blen);
else if (blen == 0){
memcpy(cp, ap, alen);
}
/*
if (alen == 0)
while (blen--)
*cp++ = *bp++;
else
while (alen--)
*cp++ = *ap++;
*/
}
void msort(int *arr, int len)
{
int mid = len / 2;
int llen = mid;
int rlen = len - mid;
int *l = malloc(llen);
int *r = malloc(rlen);
int i;
if (len <= 1)
return;
for (i = 0; i < llen; i++)
l[i] = arr[i];
for (i = mid; i < mid + rlen; i++)
r[i-mid] = arr[i];
msort(l, llen);
msort(r, rlen);
merge(l, llen, r, rlen, arr);
free(l);
free(r);
}
int main()
{
int arr[] = {4,3, 2, 1};
int len = sizeof(arr) /sizeof(int);
int x[] = {1,3,5,7};
int y[] = {2,4,6,8};
msort(arr, len);
pr_array(arr, len);
return(0);
}
memcpy does not work for overlapping memory, use memmove instead
Where does it overlap? I found a big problem, I was passing in size
instead of size * sizeof(int).
--
To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
John de la Garza
2014-10-19 22:14:27 UTC
Permalink
=20
=20
=20
=20
Can anone see why these two pieces of code would behave different=
ly?
They are used in a mergesort merge
=20
the top one ends up with c (cp points to an offset in c)
1 2 3 1
=20
the bottom one (not commented out)
results in 1 2 3 4 (correct)
=20
/*
if (alen =3D=3D 0)
memcpy(cp, bp, blen);
else if (blen =3D=3D 0){
memcpy(cp, ap, alen);
}
*/
if (alen =3D=3D 0)
while (blen--)
*cp++ =3D *bp++;
else
while (alen--)
*cp++ =3D *ap++;
=20
=20
if you want to read it with more context see below
---------------------------------------------------
=20
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
=20
void pr_array(int *a, int len)
{
int i;
for (i =3D 0; i < len; i++)
printf("%d ", a[i]);
printf("\n");
}
void merge(int *a, int alen, int *b, int blen, int *c)
{
int *ap =3D a;
int *bp =3D b;
int *cp =3D c;
=20
while (alen && blen) {
if (*ap <=3D *bp) {
*cp++ =3D *ap++;
alen--;
} else{
*cp++ =3D *bp++;
blen--;
}
}
if (alen =3D=3D 0)
memcpy(cp, bp, blen);
else if (blen =3D=3D 0){
memcpy(cp, ap, alen);
}
/*
if (alen =3D=3D 0)
while (blen--)
*cp++ =3D *bp++;
else
while (alen--)
*cp++ =3D *ap++;
*/
}
=20
void msort(int *arr, int len)
{
int mid =3D len / 2;
int llen =3D mid;
int rlen =3D len - mid;
int *l =3D malloc(llen);
int *r =3D malloc(rlen);
int i;
=20
if (len <=3D 1)
return;=09
for (i =3D 0; i < llen; i++)
l[i] =3D arr[i];
for (i =3D mid; i < mid + rlen; i++)
r[i-mid] =3D arr[i];
msort(l, llen);
msort(r, rlen);
merge(l, llen, r, rlen, arr);
free(l);
free(r);
}
int main()
{
int arr[] =3D {4,3, 2, 1};
int len =3D sizeof(arr) /sizeof(int);
int x[] =3D {1,3,5,7};
int y[] =3D {2,4,6,8};
=20
msort(arr, len);
pr_array(arr, len);
return(0);
}
=20
memcpy does not work for overlapping memory, use memmove instead
=20
Where does it overlap? I found a big problem, I was passing in siz=
e
instead of size * sizeof(int).
=20
My intention was to point a possible error source, I haven=E2=80=99t =
looked carefully at your code.
=20
thanks

I just ran valgrind and realized I made the same mistake in many places
--
To unsubscribe from this list: send the line "unsubscribe linux-c-progr=
amming" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Continue reading on narkive:
Loading...