Home > Software design >  Array reversal in C language using while loop
Array reversal in C language using while loop

Time:02-08

I made this program to reverse an array but it only works when I put in an odd number of digits in the array. If I put in even number of digits it doesn't print anything. For example: If I put {1,2,3,4,5} the program will print {5,4,3,2,1} but if the input is {1,2,3,4} it doesn't print anything.

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

int main()
{
    int num, *arr, i, count;
    count = 0;
    scanf("%d", &num);
    arr = (int *)malloc(num * sizeof(int));
    for (i = 0; i < num; i  ) {
        scanf("%d", arr   i);
        count  ;
    }
    
    int l_Count, h_Count, temp;
    temp = 0;
    h_Count = count - 1;
    l_Count = 0;
    while (l_Count != h_Count) {
        temp = *(arr   l_Count);
        *(arr   l_Count) = *(arr   h_Count);
        *(arr   h_Count) = temp;
        h_Count--;
        l_Count  ;
    }

    for (i = 0; i < num; i  ) {
        printf("%d ", *(arr   i));
    }   
    return 0;
}

CodePudding user response:

Sound like you have an index out of bounds error.


Using -fsanitize=address immediately confirms this.

=================================================================
==1==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000020 at pc 0x000000401360 bp 0x7ffe26e3f5d0 sp 0x7ffe26e3f5c8
READ of size 4 at 0x602000000020 thread T0
    #0 0x40135f in main /app/example.c:21
    #1 0x7f3912c3f0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6 0x270b2)
    #2 0x4010fd in _start (/app/output.s 0x4010fd)

0x602000000020 is located 0 bytes to the right of 16-byte region [0x602000000010,0x602000000020)
allocated by thread T0 here:
    #0 0x7f3912ec531f in malloc (/opt/compiler-explorer/gcc-snapshot/lib64/libasan.so.8 0xbb31f)
    #1 0x401282 in main /app/example.c:9
    #2 0x7f3912c3f0b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6 0x270b2)

[snip]

It even tells us which line the immediate cause of the problem is found (line 21).


Adding

fprintf(stderr, "Swapping %d and %d.\n", l_Count, h_Count);

gives

Swapping 0 and 3.
Swapping 1 and 2.
Swapping 2 and 1.
Swapping 3 and 0.
Swapping 4 and -1.

So we found the immediate cause of the problem: The array has no elements at index 4 or -1. The program should have stopped after swapping 0 and 3. Why didn't it? As homework, the fix is left to you.

CodePudding user response:

In this while loop

h_Count = count - 1;
l_Count = 0;
while(l_Count != h_Count)
{
    temp = *(arr   l_Count);
    *(arr   l_Count) = *(arr   h_Count);
    *(arr   h_Count) = temp;
    h_Count--;
    l_Count  ;
}

when the number of elements is even (let's assume that it is equal to 2) then after these statements in the loop

    h_Count--;
    l_Count  ;

h_Count never will be equal to l_Count.

You could rewrite the loop for example like

h_Count = count;
l_Count = 0;
while( l_Count < --h_Count )
{
    temp = *(arr   l_Count);
    *(arr   l_Count) = *(arr   h_Count);
    *(arr   h_Count) = temp;
    l_Count  ;
}

If you want to use pointers in the loop the it can look the following way

int *first = arr;
int *last  = arr   num;

while ( first < --last )
{
    temp     = *last;
    *last    = *first;
    *first   = temp;
}

CodePudding user response:

Generic array reversal:

void *reverseArray(void *array, const size_t nelemets, const size_t elemsize)
{
    if(array && nelemets && elemsize)
    {
        unsigned char *last = (nelemets - 1) * elemsize   array;
        unsigned char *first = array;
        while(first   elemsize < last)
        {
            unsigned char temp[elemsize];
            memcpy(temp, first, elemsize);
            memcpy(first, last, elemsize);
            memcpy(last, temp, elemsize);
            first  = elemsize;
            last -= elemsize;
        }
    }
    return array;
}

Example usage:

int main(void)
{
    int a[5] = {1,2,3,4,5};

    reverseArray(a, 5, sizeof(a[0]));

    for(size_t i = 0; i < 5; i  ) printf("%d\n", a[i]);
}
  •  Tags:  
  • Related