C - generic function: swap two items in array - c

My problem: I would like to create function that can swap any two items in array of generic type.
I have SwapG function that can swap two items of any type:
void SwapG(void * a, void * b, size_t size)
{
void * temp = malloc(size);
memcpy(temp, a, size);
memcpy(a, b, size);
memcpy(b, temp, size);
}
Here is my attempt of function that would swap two items in array of any type:
void SwapInArrayG(void ** arr, int a, int b, size_t size)
{
void * temp = malloc(size);
memcpy(temp, *(arr + a), size);
memcpy(*(arr + a), *(arr + b), size);
memcpy(*(arr + b), temp, size);
}
I'm pretty sure I messed the pointers up, still I can't find solution. I would appreciate any help :).

Adding to a void * is not defined. Cast to char *.
Possibly need to need to de-reference arr, but I think OP's signature should be adjusted instead. See #user3386109
Scale the pointer calculation #EOF
Free the allocated memory too.
I'd expect passing a void * to be sufficient.
void SwapInArrayG(void * arr, int a, int b, size_t size) {
void * temp = malloc(size);
if (size > 0) {
assert(temp);
assert(a >= 0 && b >= 0);
memcpy(temp, (char *)arr + size*a, size);
memcpy((char *)arr + size*a, (char *)arr + size*b, size);
memcpy((char *)arr + size*b, temp, size);
}
free(temp);
}
Unclear on how OP calls this function, but the following is typical.
foo_type G[some_size];
SwapInArrayG(G, index_a, index_b, sizeof *G);
Note: depending on coding goals, using indexes of type size_t is usually preferred over type int.
Note: that assert(temp); is within if (size > 0) as allocating 0 bytes may return NULL and not be out-of-memory. OTOH, size == 0 is most unusual.

Related

Inconsistency in size of array cells

i'm doing a school project implementing some sorting algorithms in C codes, and i'm working on a Binary Insertion Sort on some generic data type arrays (so i'm using void* items and void** arrays).
I have a binarySearch function that returns the index i would have to insert an item into the array to preserve the ordering of its elements (according to a given function that i pass to the sorting function), and this works correctly.
int binary_search(void **arr, void *item, long start, long end, int data_size, compFunc compare)
{
int s = start, e = end;
while (s <= e)
{
long middle = s + (e - s) / 2;
int comparison = compare(item, arr[middle]);
if (comparison == 0)
return middle;
else if (comparison > 0)
s = middle + 1;
else
e = middle - 1;
}
return s;
}
Then i have the binaryInsertSort function
void binary_insert_sort(void **arr, long arr_size, int data_size, compFunc compare)
{
long explored, j, pos;
void *current = malloc(sizeof(void*)), *holder;
if(!current){
perror("Error allocating memory\n");
exit(EXIT_FAILURE);
}
for (explored = 1; explored < arr_size; explored++)
{
memcpy(current, arr[explored], data_size);
j = explored - 1;
pos = binary_search(arr, current, 0, j, data_size, compare);
while (j >= pos)
{
holder = malloc(sizeof(void *));
memcpy(holder, (*arr) + (j + 1)*data_size, data_size);
//CRASHES HERE
memcpy((*arr) + (j + 1) * data_size, (*arr) + (j * data_size), data_size);
memcpy((*arr) + (j * data_size), holder, data_size);
j--;
free(holder);
}
}
free(current);
}
I call these functions like this
int main(int argc, char const *argv[])
{
char* arr[] = {"a", "b", "f", "d", "c", "g", "e", "1"};
int n = sizeof(arr)/sizeof(char*);
binary_insert_sort((void**)arr, n, sizeof(char*), string_compare);
print_string_array(arr, n);
return 0;
}
But it always crashes after the first memcpy , when i try to move arr[j+1] into arr[j] ; i tried doing some debugging and, after trying to print (int)(arr[1]-arr[0])(which should print the size of a cell if i understand correctly), i noticed cells have size = 2 rather than the expected sizeof(char*)=4 , so there are problem accessing them correctly when using *arr + j*data_size , since i'm moving j * 2 cells rather than j
why does this happen?
i apologize if i'm missing something basic, or if english or formatting arent right, 1st time asking
i'm doing a school project implementing some sorting algorithms in C codes, and i'm working on a Binary Insertion Sort on some generic data type arrays (so i'm using void* items and void** arrays).
You clarified in comments that what you mean is that you want a function that can sort arrays having any element type. This is exactly what the standard library's qsort() function does, so you should look to it for guidance on how such a function might look and work.
In particular, you need to understand that C has no generic data type. In particular, a void * can point to an object of any type, but void * itself is a specific, complete type, not generic in any way.* Thus, using void * items does not serve your purpose at all. Not even if you wanted to sort only arrays of pointers, because the C language does not guarantee that different pointer types have the same representation as each other, or even the same size, except only that char * and void * are required to have the same size and representation.
In other words, no, you don't have void * items, and you don't want to sort a "void ** array". And therefore no, your binarySearch() function for an array of void * does not serve your purposes -- however well it does its job, it's the wrong job.
Following qsort(), here's a signature that would serve your purpose:
typedef int (*compFunc)(const void *, const void *);
void binary_insert_sort(void *arr, size_t element_count, size_t element_size,
compFunc compare);
Note that the array to sort is conveyed via a pointer to its first element, received by the function as a pointer of type void * -- not void **. This does present an issue, however: you cannot perform pointer arithmetic or array indexing on a void *, because these operations are defined in terms of the size of the pointed-to type, which is unknown in this case because void is an incomplete type. But it should not be a particular surprise that such an issue arises, because the whole point of the exercise is to sort objects whose size is not known when the the function is compiled.
So what do you do? The traditional approach would be via converting to char *:
#define ELEMENT_POINTER(base, index, size) ((char *) (base) + (index) * (size))
void *element_3_for_example = ELEMENT_POINTER(arr, 3, element_size);
So a comparison would then look like this ...
int result = compare(ELEMENT_POINTER(arr, i, element_size),
ELEMENT_POINTER(arr, j, element_size));
... and a swap might look like this:
void *temp = malloc(element_size);
// ...
memcpy(temp, ELEMENT_POINTER(arr, i, element_size));
memcpy(ELEMENT_POINTER(arr, i, element_size), ELEMENT_POINTER(arr, j, element_size));
memcpy(ELEMENT_POINTER(arr, j, element_size), temp);
// ...
free(temp);
I'll leave it to you to work the actual exercise in terms of those or similar constructs.
As for the actual question ...
why does this happen?
, it's because your function is confused about whether the elements of the array are themselves the items being sorted or whether they are pointers to the elements being sorted. Erroneously assuming the latter, it makes the further questionable choice of swapping the data instead of the pointers. In this particular case, the data happen to be pointers after all, though that would not always be the case. The data they point to are arrays containing string literals, and
These arrays are not the expected size, so you have bounds overruns on both reading and writing, and
They are not writable anyway, which is probably the specific source of the error.
* One could consider void to be a generic data type, as indeed this answer could be taken to demonstrate. But you cannot declare an object to have type void, nor access an object via an lvalue of type void, so this is largely moot.
Your approach is initially wrong due the function declarations and their calls like for example
binary_insert_sort((void**)arr, n, sizeof(char*), string_compare);
^^^^^^^^^^^
That is if within the function you will dereference the pointer like for example
arr[explored]
then the expression will have the type void *. So if the original array has for example the type
char arr[] = "hello";
then in the expression above there will be used incorrect pointer arithmetic. That is instead of evaluation the value of the pointer expression like value of arr + explored * sizeof( char ) the value of the pointer expression will be evaluated like value of arr + explored * sizeof( void * ).
Also the function is inefficient. There are too many memory allocations in the while loop
while (j >= pos)
{
holder = malloc(sizeof(void *));
//...
The function should be declared at least like
void binary_insert_sort( void *arr, size_t arr_size, size_t data_size, compFunc compare);
The function binary_search has a redundant parameter start. You are calling the function always passing 0 as its argument for the parameter start
pos = binary_search(arr, current, 0, j, data_size, compare);
Instead of the parameters start and end it is enough to pass the number of elements in the sub-array. So the function could be declared like
int binary_search( const void *arr, const void *item, size_t arr_size, size_t data_size, compFunc compare);
Or similarly to the standard C function bsearch like
int binary_search( const void *item, const void *arr, size_t arr_size, size_t data_size, compFunc compare);
If the sub-array already has the element that is equal to the searched element then the function should return the position after the existent element in the sub-array instead of returning the position of the existent element.
Ok so thanks to the help of the previous comments i managed to get it somewhat going, here is the updated code
#define GET_PTR(base, offset, size) ((char *)(base) + (offset) * (size))
long binary_search(void *arr, void *item, size_t end, int data_size, compFunc compare)
{
long s = 0, e = end, middle;
int comparison;
while (s <= e)
{
middle = s + (e - s) / 2;
comparison = compare(item, GET_PTR(arr, middle, data_size));
if (comparison == 0)
return middle;
else if (comparison > 0)
s = middle + 1;
else
e = middle - 1;
}
return s;
}
void swap(void *base, long ind1, long ind2, size_t data_size)
{
void *temp = malloc(data_size);
memcpy(temp, GET_PTR(base, ind2, data_size), data_size);
memcpy(GET_PTR(base, ind2, data_size), GET_PTR(base, ind1, data_size), data_size);
memcpy(GET_PTR(base, ind1, data_size), temp, data_size);
free(temp);
}
void binary_insert_sort(void *arr, size_t arr_size, size_t data_size, compFunc cmp)
{
void *current = malloc(data_size), *holder;
long explored, shifting, bs_pos;
for (explored = 1; explored < arr_size; explored++)
{
current = GET_PTR(arr, explored, data_size);
shifting = explored - 1;
bs_pos = binary_search(arr, current, shifting, data_size, cmp);
while (shifting >= bs_pos)
{
swap(arr, shifting, shifting + 1, data_size);
shifting--;
}
}
free(current);
}
and this seems to work, it manages to correctly sort an array of int and of a 'Person' struct when called like this
int main(int argc, char const *argv[])
{
// char *string_arr[] = {"a", "b", "f", "d", "c", "g", "e", "1"};
// int char_size = sizeof(arr) / sizeof(arr[0]);
// print_string_array((char**)arr, char_size);
// binary_insert_sort((void*)arr, char_size, sizeof(char*), string_compare);
// print_string_array((char**)arr, char_size);
int int_arr[] = {5, 3, 2, 4, 0, 6, 14, -4, 0, 32, 2, -1};
int int_size = sizeof(int_arr) / sizeof(int_arr[0]);
print_int_array((int*)int_arr, int_size);
binary_insert_sort((void*)int_arr, int_size, sizeof(int), int_compare);
print_int_array((int*)int_arr, int_size);
Person p_arr[] = {{3, "fabio"}, {5, "marco"}, {0, "giulio"}, {2, "alberto"}, {1, "gabri"}};
int p_size = sizeof(p_arr)/sizeof(p_arr[0]);
for(int i =0;i<p_size;i++) print_person(&(p_arr[i]));
// binary_insert_sort(p_arr, p_size, sizeof(Person), person_int_cmp);
binary_insert_sort(p_arr, p_size, sizeof(Person), person_string_cmp);
for(int i =0;i<p_size;i++) print_person(&(p_arr[i]));
return 0;
}
But for some reason, the string array just wont sort: i put some debug prints and to me it seems like the problem is that when i compare them, what's really being compared is their address, as the value of comparison in binary_search is always 1 when it's sorting char_arr
Here are the functions being used:
typedef struct {
int id;
char* name;
} Person;
int person_int_cmp(void* p1, void* p2)
{
Person *a = (Person*)p1;
Person *b = (Person*)p2;
return a->id - b->id;
}
int person_string_cmp(void* p1, void* p2)
{
Person *a = (Person*)p1;
Person *b = (Person*)p2;
return strcmp(a->name, b->name);
}
void print_person(void* p){
Person* a = (Person*)p;
printf("%d: %s\n", a->id, a->name);
}
int string_compare(void *a, void *b)
{
char * str1 = (char *)a;
char * str2 = (char *)b;
return strcmp(str1, str2);
}
int int_compare(void *n1, void *n2)
{
int n01 = *(int *)n1, n02 = *(int *)n2;
return n01 - n02;
}
void print_int_array(int *arr, long size)
{
printf("\t[");
for (int i = 0; i < size; i++) printf("%d -> ", arr[i]);
printf("]\n");
}
void print_string_array(char** arr, long size)
{
printf("\t[");
for (int i = 0; i < size; i++) printf("%s -> ", arr[i]);
printf("]");
}
Am i treating the string array in some wrong way i am not aware of? What's even weirder to me is that it's able to correctly sort the Person array by the names (which are strings) but not an array of just strings
If anyone can point me what i'm doing wrong thanks so much

Derefernecing a pointer changes its value

I was trying to implement rust-style vectors in c, which is defined as
typedef struct
{
int *ptr, // pointer to starting element
int len, // length of the vector
int cap, // capacity; it does not reallocate the whole vector till len == cap
} vector;
I got almost everything working, except the get-value function. Calling vec_getval function always changes the 3rd and 4th elements to 1936877926 and 10 respectively, no matter the length of the vector. Here is all the relevant code with error checking omitted:
#define ELEMENT_SIZE sizeof(int)
extern vec_data vec_getval(vector *vec, size_t index)
{
return *(vec->ptr + (ELEMENT_SIZE * index));
}
extern void vec_push(vector *vec, vec_data val)
{
if (vec->len < vec->cap) // Don't reallocate if length < capacity
{
*(vec->ptr + (ELEMENT_SIZE * vec->len)) = val;
vec->len++;
return;
}
realloc(vec->ptr, ELEMENT_SIZE * (vec->len + 1));
*(vec->ptr + (ELEMENT_SIZE * vec->len)) = val;
vec->len++;
vec->cap++;
}
extern void vec_with_capacity(vector *vec, size_t cap)
{
vec->ptr = (int *)malloc(ELEMENT_SIZE * cap);
vec->cap = cap;
vec->len = 0;
}
int main(int argc, char **args)
{
vector vec;
vec_with_capacity(&vec, 5);
vec_push(&vec, 50u);
vec_push(&vec, 15u);
vec_push(&vec, 40u);
vec_push(&vec, 80u);
vec_push(&vec, 70u);
printf("first value\t: %d\n", vec_getval(&vec, 0)); // Works as expected, but changes 3rd and 4th elements
printf("third value\t: %d\n", vec_getval(&vec, 2)); // Does not work fine!
return 0;
}
And here's the output:
first value : 50
third value : 1936877926
For any pointer or array p and index i, the expression *(p + i) is exactly equal to p[i].
Now if we do this transformation of *(vec->ptr + (ELEMENT_SIZE * index) we get vec->ptr[ELEMENT_SIZE * index]. Which is probably not what you had in mind.
Assuming that sizeof(int) (what ELEMENT_SIZE expands to) is 4 (very common) then attempting to use index 2 will actually use index 8 (4 * 2). Which is out of bounds of your allocated memory (as it only contains 5 elements), and leads to undefined behavior.
The solution is simple: Don't multiply with ELEMENT_SIZE when accessing elements of your array.
You have another two very serious errors as well:
realloc(vec->ptr, ELEMENT_SIZE * (vec->len + 1))
*(vec->ptr + (ELEMENT_SIZE * vec->len)) = val;
Because the first line is missing the semicolon, the statement becomes
realloc(vec->ptr, ELEMENT_SIZE * (vec->len + 1)) * (vec->ptr + (ELEMENT_SIZE * vec->len)) = val;
And that doesn't make any sense.
The second problem, besides the missing semicolon, is that realloc can allocate a new memory area, which it then returns a pointer to. That would make the old pointer invalid as it then points to memory that you no longer own. Always use what realloc returns.
But also note that realloc can return NULL, in which case the old pointer remains valid, so always use a temporary variable:
int *new_ptr = realloc(vec->ptr, ELEMENT_SIZE * (vec->len + 1));
if (new_ptr == NULL)
{
// TODO: Handle error
}
vec->ptr = new_ptr;
vec->ptr[vec->len] = val;

Generic quicksort not working

I'm trying to make a generic quicksort function, and I fail to understand what's wrong with what I'm doing, because it's not working properly.
Here is my code:
typedef bool (*CmpFunction)(void*, void*);
void swap(void *c1, void *c2)
{
assert(c1 && c2);
int c = *(int*)c1;
*(int*)c1 = *(int*)c2;
*(int*)c2 = c;
}
void quick_sort(void* a, int n, CmpFunction swap)
{
int p, b = 1, t = n - 1;
if (n < 2)
return;
swap((char*)a, (char*)a+n/2);
p = *(int*)a;
while(b <= t) {
while(t >= b && (char*)a + t >= p )
t--;
while(b <= t && (char*)a + b < p)
b++;
if ( b < t)
swap((char*)a+(b++), (char*)a+(t--));
}
swap((char*)a, (char*)a+t);
quick_sort(a, t, swap);
n=n-t-1;
quick_sort(a + t + 1, n, swap);
}
While the original quicksort function, without me trying to make it generic is:
void quick_sort(int a[], int n)
{
int p, b = 1, t = n - 1;
if (n < 2)
return;
swap(&a[0], &a[n/2]);
p = a[0];
while(b <= t) {
while(t >= b && a[t] >= p )
t--;
while(b <= t && a[b] < p)
b++;
if ( b < t)
swap(&a[b++], &a[t--]);
}
swap(&a[0], &a[t]);
quick_sort(a, t);
n=n-t-1;
quick_sort(a + t + 1, n);
}
void swap(int *c1, int *c2)
{
int c = *c1;
*c1 = *c2;
*c2 = c;
}
I'm using this main():
int main(){
char b[] = {'a','t','b','c','y','s'};
int c[] = {1,4,6,3,5,7};
quick_sort(c, 6, &swap);
for (int i=0;i<6;i++)
printf("%d | ", c[i]);
return 0;
}
Now we all agree that the output should be:
1, 3, 4, 5, 6, 7
which is indeed what I get when running the NOT generic function.
When I run my generic(upper) function I get basically trash.
You all have any ideas where I'm wrong? :)
The most obvious issue: Your input data is an int array, typecasted into a void * pointer, then forced into a char * pointer:
swap((char*)a, (char*)a+n/2);
Here you force that into a char * pointer, and jumping n/2 into it.
char * is an array of 1 byte size elements
int * is an array of 2, 4 or 8 byte size elements depending on compiler/OS/CPU.
So char *a +1, void give you the second byte of the first element of the initial array.
qsort is a generic sorting function. You give it an array, the size of the elements in the array, the number of elements, and a comparison function.
typedef int(*compare)(const void*, const void*);
void quicksort(void *base, size_t num_elements, size_t width, compare *cmp);
To move through the array the sorting function needs to know the width of each element so it can do the pointer arithmetic correctly. An array of char will be 1 byte per element. An array of int is probably 4 bytes. double will be 8. base[4] of a char array is base + 4*1, but it's base + 4*4 for an int array. Ultimately base[n] is base + (n * width).
To avoid making assumptions about the data in the elements, or how you want them sorted, the compare is used to compare elements for sorting. It returns < 0 if a < b, 0 if a == b and > 0 if a > b. This allows it to be as simple as return a - b for most numbers.
An example function for comparing integers:
int cmp_int(const void* _a, const void* _b) {
/* Do the casting separately for clarity */
int *a = (int *)_a;
int *b = (int *)_b;
return *a - *b;
}
There's no need to pass in a swap function. So long as you know the size of the elements a single swap function will serve. The one from #HonzaRemeš' answer works.
void swap(void * a, void * b, size_t size) {
/* Temp buffer large enough to contain an element */
char tmp[size];
memcpy(tmp, a, size);
memcpy(a, b, size);
memcpy(b, tmp, size);
}
With all this in mind, your function is not being given the element size (ie. width) so it cannot correctly move through the array. It's also unnecessarily passing in a swap function, but there's no need for this if you know the size of the elements. And you're lacking a proper comparison function to compare elements. Not much of a generic sort function if it can't compare things to sort them.
You are trying to do something the C language is not very appropriate for. If you want to do it, you need some background knowledge about pointer arithmetics.
Specifically, for a T *, where T is a type with size N (sizeof(T) == N),
T * ptr;
ptr = (T *) 0x0100;
ptr = ptr + 1;
// ptr now has value 0x100 + N
That means you can't have a generic function which will operate on data arrays without knowing the size of the array element.
So I suggest you rewrite your quick_sort and swap functions to incorporate size parameters. You then cast your pointers to char * and use the size parameter to make the functions work correctly. Example swap function follows.
void swap(void * c1, void * c2, size_t size) {
char tmp[size]; // temporary buffer big enough to contain c1 data
memcpy(tmp, c1, size);
memcpy(c1, c2, size);
memcpy(c2, tmp, size);
}
Modifying quick_sort is left as an exercise :). Remember though that when you don't know the size of your data, you must use memcpy(dst, src, size) instead of dst = src, you must use memcmp(a1, a2, size) >= 0 instead of a1 >= a2 and that your pointer access must be multiplied by size (exerpt from quick_sort follows):
EDIT: #Schwern points out in the comments why using memcmp() may not work. Comparing values of unknown size and format (endianness, float X int) would probably require a generic comparison function (which would likely be next to impossible to write). That takes us back to C's ill-suitedness for this task.
void quick_sort(void *a, int n, size_t size) {
char[size] p;
int b = 1, t = n - 1;
if(n < 2)
return;
// Using new swap with 'size' parameter
swap(&a[0], &((char *)a)[n / 2 * size], size);
// or swap((char *)a + 0, (char*)a + (n / 2 * size), size);
memcpy(p, a, size);
while(b <= t) {
while(t >= b && memcmp((char *)a[t * size], p, size) >= 0) {
...
}
You can then write wrapper macros to pass the size parameter to the quick_sort function.
#define QSORT(arr, n) quick_sort((arr), (n), sizeof((arr)[0]))

How to copy dynamically allocated array of struct?

I have been struggling with this. What I have found here on stackoverflow, and other places was to just do:
memcpy(&a, &b, sizeof(b));
But for me, that did not work. So I thought, I share what worked for me without any unexpected behavior.
Assume you have:
#define N 42
struct struct_name *a = malloc(sizeof *a * N); // allocate N objects
struct struct_name *b = malloc(sizeof *b * N); // allocate N objects
then the correct memcpy call to copy the array of structure objects is:
memcpy(a, b, sizeof *a * N);
In my case previous solutions did not work properly, e.g. the one in the question! (it copied about half of only the first element).
So in case, somebody needs a solution, that will give you correct results, here it is:
memcpy(a, b, n * sizeof(*b));
More detail:
int i, n = 50;
struct YourStruct *a, *b;
a = calloc(n, sizeof(*a));
b = malloc(n * sizeof(*b));
for (i = 0; i < n; ++i) {
// filling a
}
memcpy(b, a, n * sizeof(*a)); // <----- memcpy 'n' elements from 'a' to 'b'
if (a != NULL) free(a); // free 'a'
a = calloc(2*n, sizeof(*a)); // 'a' is size 2n now
memcpy(a, b, n * sizeof(*b)); // <------ memcpy back the 'n' elements from 'b' to 'a'
// do other stuff with 'a' (filling too)...
Some notes:
I used calloc for a, because in the '// filling a' part I was doing
operations that required initialized data.
I could have used realloc as well.
I was kind of doing a dynamically growing array (with doubling size -> log(n)), but here I simplified it.
You should check, if memory allocation is successful or not (a,b NULL or not). But here, I removed those checks for simplification.

How to edit a void type array

How does one edit void pointers? Obviously, this is possible in C, because there are many standard library functions that do this.
I thought I'd implement a function swapping two array elements (I know there is a standard function for it, it's just an exercise), so ideally I'd want to do this:
void swap(void *arr, int a, int b, int elSize) {
void arrEl = arr[a];
arr[a] = arr[b];
arr[b] = arrEl;
}
Of course, I can't dereference a void pointer, nor can I have a variable of type void, so I have to work around that somehow, but I discovered I don't know how to edit a void type array.
So how should I implement above pseudo-C?
I saw this thread, but I am not sure how to apply that and think seeing the correct version of above pseudo-C will make it a bit more clear.
Technically you can't have a void array or void values. You can have a void pointer that points to an array of some type.
To use it you have to cast it to a non-void pointer, like e.g.
int value0 = ((int *) arr)[0];
And the simplest solution to not have to do this is to declare the pointer arr as a pointer to the type it actually is.
If you can't do that, then if you have the element size, you can declare temporary variable-length arrays to handle the swapping, like
char tmp[elSize];
memcpy(tmp, (char *) arr + elSize * a, elSize);
memcpy((char *) arr + elSize * a, (char *) arr + elSize * b, elSize);
memcpy((char *) arr + elSize * b, tmp, elSize);
The above swaps between the values at "index" a and b.
Joachim was a bit faster, but I'll add my answer anyway.
#include <string.h>
void swap(void *arr, size_t a, size_t b, size_t elSize) {
char temp[elSize];
memcpy(temp, (char*)arr+a*elSize, elSize);
memcpy((char*)arr+a*elSize, (char*)arr+b*elSize, elSize);
memcpy((char*)arr+b*elSize, temp, elSize);
}
#include <stdio.h>
int main(void)
{
int array[3] = {1,13,42};
char text[] = "This is text\n" ;
swap(text, 0, 2, 4);
printf("%s", text );
swap(array, 0, 2, sizeof array[0] );
printf("{%d %d %d}\n", array[0], array[1], array[2] );
return 0;
}
By assigning arr[a] to arrEl, in fact you are dereferencing a void type pointer. And for this you must have to cast it before doing any operation to it. As;
int arrEl = ((int *)arr)[a];
or
int arrEl = *((int *)arr + a);

Resources