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