Home > OS >  C: copying array in function by using pointers gave unusual result, why did it half work?
C: copying array in function by using pointers gave unusual result, why did it half work?

Time:10-14

So I don't want to make a function for every data type, I would like to be able to just use pointers to fix the problem. Tried the idea with a function for copying an array. I didn't get the result i expected or wanted, even if it had just gone entirely wrong with the new_arr not changing at all i would be ok this isn't it. but it gave me hope.

void *copy_array(const void *arr[], const void *new_arr[], size_t arr_len, size_t type_size) {
    for (int i = 0; i < arr_len ;   i) {
        *(new_arr   (i * type_size)) = *(arr   (i * type_size));
    }
}

void print_int_array(int * array, int length) {
    for (int i = 0; i < length;   i) {
        printf("\nelement %d = %d", i, array[i]);
    }
}

int main() {
    int arr[ARRAY_LENGTH]     = {12, 3,4};
    int new_arr[ARRAY_LENGTH] = {0, 0, 0};

    print_int_array(arr, ARRAY_LENGTH);
    print_int_array(new_arr, ARRAY_LENGTH);

    copy_array(&arr, &new_arr, ARRAY_LENGTH, sizeof(new_arr[0]));

    print_int_array(arr, ARRAY_LENGTH);
    print_int_array(new_arr, ARRAY_LENGTH);
    return 0;
}

Console returns this for some reason, it gets the 12 and the 3 by why not the 4?

element 0 = 12
element 1 = 3
element 2 = 4
element 0 = 0
element 1 = 0
element 2 = 0
element 0 = 12
element 1 = 3
element 2 = 4
element 0 = 12
element 1 = 3
element 2 = 0

CodePudding user response:

You declared a function

void *copy_array(const void *arr[], const void *new_arr[], size_t arr_len, size_t type_size) {

where the both first parameters have the qualifier const. So the function declaration is incorrect.

Instead it would be better to declare the first parameter of the function print_int_array with the qualifier const and the second parameter as having the type size_t

void print_int_array( const int * array, size_t length) {

On the other hand, the expressions

*(new_arr   (i * type_size))

and

*(arr   (i * type_size))

have pointer types. Their sizes can be greater than the size of an object of the type int. For example sizeof( void * ) can be equal to 8 while sizeof( int ) can be equal to 4.

Thus the function can invoke undefined behavior.

Apart from that the function has a non-void return type but returns nothing.

Also there is no great sense to call the function passing pointers to arrays like

copy_array(&arr, &new_arr, ARRAY_LENGTH, sizeof(new_arr[0]));

where each expression has the type int( * )[3].

The function can be defined the following way as shown in the demonstration program below.

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

void copy_array( void *new_arr, const void *arr, size_t arr_len, size_t type_size ) 
{
    for (size_t i = 0; i < arr_len; i  )
    {
        memcpy( new_arr, arr, type_size );
        new_arr = ( char * )new_arr   type_size;
        arr = ( const char * )arr   type_size;
    }
}

int main( void )
{
    enum { ARRAY_LENGTH = 3 };
    int arr[ARRAY_LENGTH] = { 12, 3,4 };
    int new_arr[ARRAY_LENGTH] = { 0, 0, 0 };

    printf( "arr    : " );
    for (size_t i = 0; i < ARRAY_LENGTH; i  )
    {
        printf( "%d ", arr[i] );
    }
    putchar( '\n' );

    printf( "new_arr: " );
    for (size_t i = 0; i < ARRAY_LENGTH; i  )
    {
        printf( "%d ", new_arr[i] );
    }
    putchar( '\n' );

    putchar( '\n' );

    copy_array( new_arr, arr, ARRAY_LENGTH, sizeof( int ) );

    printf( "arr    : " );
    for (size_t i = 0; i < ARRAY_LENGTH; i  )
    {
        printf( "%d ", arr[i] );
    }
    putchar( '\n' );

    printf( "new_arr: " );
    for (size_t i = 0; i < ARRAY_LENGTH; i  )
    {
        printf( "%d ", new_arr[i] );
    }
    putchar( '\n' );
}

The program output is

arr    : 12 3 4
new_arr: 0 0 0

arr    : 12 3 4
new_arr: 12 3 4
  • Related