1

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;
}
4
  • 3
    Now would be a good time to learn to debug your own code. Run your program in a debugger and step thru it line by line. More debugging tips here: How to debug small programs. Commented Feb 7, 2022 at 20:34
  • Based on the description (not a look of the code), that sounds like an out of bounds error. -fsanitize=address should find this easily. Update: yup Commented Feb 7, 2022 at 20:37
  • 1
    The amount of effort spent on this code avoiding actually advancing pointers is sort of breathtaking. And there is utterly useless activity to boot (ex: what is count really used for? A synonym for num ?). Also, consider what can happen when the number of elements is even. Won't an ascending low counter and descending high counter eventually reside next to each other, then pass each other, thereby never tripping the very specific l_Count != h_Count condition ? Commented Feb 7, 2022 at 20:42
  • 1
    while(l_Count != h_Count) --> while(l_Count < h_Count) Commented Feb 7, 2022 at 20:42

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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;
}

Comments

0

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]);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.