carraysfunctionreversedefinition

Why my new array only copy and reverse first 10 elements about old array?


I want to copy and reverse a array in C pointer, but I found the result can only shown first 10 elements, why?

Original array: 0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361
Reversed array: 81 64 49 36 25 16 9 4 1 0 29274861 12333 14041000 14036848 0 0 14036820 0 14036816 0

my func:

int * reverse_copy(int *A, int N) { 
    int *B,tmp; 
    for (B=A+N-1;A<B;A++,B--){
      tmp=*A;
      *A=*B;
      *B=tmp;
    }
}

main

int * reverse_copy(int *A, int N);  
int main(int argc, char *argv[]) {   
    int N = 20;int i;int *A = NULL, *B = NULL;   
    if (argc > 1)   // first command line parameter
        N = atoi(argv[1]);  
    // allocate, fill, and print input array
    A = (int*) malloc(N * sizeof(int));
    for (i = 0; i < N; i++)
        A[i] = i*i;       
    // call task function
    B = reverse_copy(A, N);     
    // free allocated memory
    free(A);
    free(B);
    return 0;
}   

Solution

  • For starters the name of the function reverse_copy only confuses readers because the function copies nothing. It reverses an array in place.

    So it is better to name the function simply as reverse.

    Secondly, the function has the return type int * but returns nothing. There is no sense to declare the return type of the function as int * instead of void provided that the function does not allocate dynamically a new array..

    As a result this statement

    B = reverse_copy(A, N);
    

    does not make sense and invokes undefined behavior.

    You allocated only one array that is pointed to by the pointer A. The pointer B does not point to a newly dynamically allocated array. So this statement

    free(B);
    

    again invokes undefined behavior.

    Here is a demonstrative program that shows how the two functions, reverse and reverse_copy, can be implemented using pointers.

    #include <stdio.h>
    #include <stdlib.h>
    
    void reverse( int *a, size_t n )
    {
        if ( n != 0 )
        {
            for ( int *b = a + n; a < --b; ++a )
            {
                int tmp = *a;
                *a = *b;
                *b = tmp;
            }
        }
    }
    
    int * reverse_copy( const int *a, size_t n )
    {
        int *b = NULL;
        
        if ( n != 0 )
        {
            b = malloc( n * sizeof( int ) );
            
            for ( int *p = b + n; p-- != b; ++a )
            {
                *p = *a; 
            }
        }
        
        return b;
    }
    
    int main(void) 
    {
        int a[] = 
        { 
            0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361 
        };
        
        const size_t N = sizeof( a ) / sizeof( *a );
        
        printf( "Original array: " );
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "%d ", a[i] );
        }
        
        putchar( '\n' );
        
        reverse( a, N );
        
        printf( "Reversed array: " );
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "%d ", a[i] );
        }
        
        putchar( '\n' );
        
        putchar( '\n' );
        
        printf( "Original array: " );
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "%d ", a[i] );
        }
        
        putchar( '\n' );
        
        int *b = reverse_copy( a, N );
        
        printf( "Reversed array: " );
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "%d ", b[i] );
        }
        
        putchar( '\n' );
        
        free( b );
        
        return 0;
    }
    

    The program output is

    Original array: 0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361 
    Reversed array: 361 324 289 256 225 196 169 144 121 100 81 64 49 36 25 16 9 4 1 0 
    
    Original array: 361 324 289 256 225 196 169 144 121 100 81 64 49 36 25 16 9 4 1 0 
    Reversed array: 0 1 4 9 16 25 36 49 64 81 100 121 144 169 196 225 256 289 324 361
    

    An alternative and more flexible approach of implementation of the function reverse_copy is to provide to the function an already existent/allocated array.

    Here is a demonstrative program

    #include <stdio.h>
    #include <stdlib.h>
    
    int * reverse_copy( const int *a, size_t n, int *b )
    {
        for ( const int *p = a + n; p != a; ++b )
        {
            *b = *--p;
        }
        
        return b;
    }
    
    int main(void) 
    {
        int a[] = { 0, 1, 2, 3, 4, 5 };
        
        const size_t N = sizeof( a ) / sizeof( *a );
        
        printf( "Original array: " );
        for ( size_t i = 0; i < N; i++ )
        {
            printf( "%d ", a[i] );
        }
        
        putchar( '\n' );
        
    
        int *b = malloc( 2 * N * sizeof( int ) );
    
        int *p = reverse_copy( a, N, b );;
        
        for ( const int *q = a; q != a + N; ++q, ++p )
        {
            *p = *q;
        }
        
        printf( "Reversed array: " );
        for ( size_t i = 0; i < 2 * N; i++ )
        {
            printf( "%d ", b[i] );
        }
        
        putchar( '\n' );
        
        free( b );
        
        return 0;
    }
    

    The program output is

    Original array: 0 1 2 3 4 5 
    Reversed array: 5 4 3 2 1 0 0 1 2 3 4 5