2

I am trying to write a code that receives the number of input numbers and integers, then reverses those order and prints them out. When I run this code it freezes from the for loop in input_integer function. What am I doing wrong?

# include <stdio.h>
# include <stdlib.h>

void input_integer (int *arr, int *arrSize);
void inverse_reorder (int *arr, int *arrSize);

int main (void){
    int* arrSize;
    int* arr;
    int i;

    input_integer(arr, arrSize);
    printf("inputted data : ");
    for ( i = 0; i < *arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }
    inverse_reorder(arr, arrSize);
    printf("reversed data : ");
    for ( i = 0; i < *arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }

    return 0;
}

void input_integer (int* arr, int *arrSize){
    printf("Array size = ? ");
    scanf("%d", arrSize);
    int i;
    for( i = 0; i < *arrSize ; i++ ){
        scanf("%d", *(arr + i));
    }   
}

void inverse_reorder (int * arr, int *arrSize){
    int i;
    int temp = 0;
    for ( i = 0; i < *arrSize ; i++ ){
        temp = *(arr+i);
        *(arr+i) = *(arr + *arrSize - i);
        *(arr + *arrSize - i) = temp;
    }
}
2
  • Check your compiler settings: I am pretty sure you should get some warning from scanf("%d", *(arr + i));. Commented Jun 6, 2017 at 12:25
  • Debugger................. Commented Jun 6, 2017 at 13:28

5 Answers 5

1

You declare arrSize as an int *, but you never assign a value to that pointer, so it's value is indeterminate. When you later pass the value of that pointer to scanf, it reads that garbage value and attempts to write to that invalid address. This invokes undefined behavior. You also never allocate space for arr. Also, when you read in each array element, you're passing in an array value instead of the address of an array element.

You should declare arrSize as an int in your main function, then pass its address to input_integer to populate it. Then in input_integer, you need use malloc to allocate space for the array. You'll also need to pass in the address of arr to write to it.

int main (void){
    int arrSize;
    int *arr;
    int i;

    input_integer(&arr, &arrSize);
    printf("inputted data : ");
    for ( i = 0; i < arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }
    inverse_reorder(arr, arrSize);
    printf("reversed data : ");
    for ( i = 0; i < arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }

    return 0;
}

void input_integer (int **arr, int *arrSize){
    printf("Array size = ? ");
    scanf("%d", arrSize);
    *arr = malloc(*arrSize * sizeof(int));
    if (*arr == NULL) {
        perror("malloc failed");
        exit(1);
    }
    int i;
    for( i = 0; i < *arrSize ; i++ ){
        scanf("%d", *arr + i);
    }   
}

void inverse_reorder (int *arr, int arrSize){
    int i;
    int temp = 0;
    for ( i = 0; i < arrSize ; i++ ){
        temp = *(arr+i);
        *(arr+i) = *(arr + arrSize - i);
        *(arr + arrSize - i) = temp;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

1

The %d format specifier in scanf expects an int* as its parameter. However, you are dereferencing the pointer when you do this: *(arr + i). You don't need the *.

However, in your main function, you declare two pointers that don't point anywhere. You need to allocate some storage e.g.

int main (void){
    int arrSize;
    int i;

    int* arr = input_integer(&arrSize);

I changed input_integer to return the int pointer of the array.

And input_integer will allocate storage based on the input array size:

int* input_integer (int *arrSize){
    printf("Array size = ? ");
    scanf("%d", arrSize);
    // Should really validate the size here
    int *arr = calloc(*arrSize, sizof *arr); 
    int i;
    for( i = 0; i < *arrSize ; i++ ){
        scanf("%d", arr + i);
    } 
    return arr;  
}

Then your main function should always use arrSize without dereferencing it and also free the pointer at the end.

Comments

0

arrSize is not a pointer it should be a value for the program to run. You can't compare the incremented i in the loop to the reference value of arrSize otherwise it will be looping for long and long as the loop's limit would be the pointer address. You should access the pointers only when writing , never on reading (unless it's intended).

Comments

0

Variables arrSize and arr are not initialized and have indeterminate values

int* arrSize;
int* arr;

However inside for example the function input_integer their indeterminate values are used.

As result the program in whole has undefined behavior.

There is no need to declare the variable arrSize as a pointer.

The variable arr must be passed to the function input_integer by reference. Otherwise the function will deal with a copy of the value of the variable and the original value of the variable will not be changed.

So the function should be declared at least like

void input_integer (int **arr, int *arrSize);
                        ^^^^^

The function inverse_reorder in fact does not reverse the order of the elements of the array. That is it reverse the order twice keeping the original order as the result.

You need also to free the allocated array.

The program and the functions can look the following way

#include <stdio.h>
#include <stdlib.h>

void input_integer( int **a, size_t *n );
void inverse_reorder( int *a, size_t n );

int main(void) 
{
    int *a;
    size_t n;

    input_integer( &a, &n );

    if ( n )
    {
        printf( "inputted data : " );

        for ( size_t i = 0; i < n ; i++ )
        {
            printf( "%d, ", *( a + i ) );
        }
        putchar( '\n' );

        inverse_reorder( a, n );

        printf( "reversed data : " );

        for ( size_t i = 0; i < n ; i++ )
        {
            printf( "%d, ", *( a + i ) );
        }
        putchar( '\n' );

        free( a );
    }

    return 0;
}

void input_integer( int **a, size_t *n )
{
    *a = NULL;
    *n = 0;

    printf( "Array size = ? " );

    if ( scanf( "%zu", n ) == 1 && *n != 0 )
    {
        *a = malloc( *n * sizeof( int ) );

        printf( "enter %zu integers: ", *n );
        for ( size_t i = 0; i < *n; i++ ) scanf( "%d", *a + i );
    }
}

void inverse_reorder( int *a, size_t n )
{
    for ( size_t i = 0; i < n / 2; i++ )
    {
        int tmp = *( a + i );
        *( a + i ) = *( a + n - i - 1 );
        *( a + n - i - 1 ) = tmp;
    }
}

The program output is

Array size = ? 10
enter 10 integers: 0 1 2 3 4 5 6 7 8 9
inputted data : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
reversed data : 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 

You may add a check that the memory was allocated successfully by yourself.

Comments

0

Use gcc -Wall to compile your programs.

reversing.c: In function ‘input_integer’:
reversing.c:31:13: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
     scanf("%d", *(arr + i));
            ~^   ~~~~~~~~~~
reversing.c: In function ‘main’:
reversing.c:12:3: warning: ‘arr’ is used uninitialized in this function [-Wuninitialized]
   input_integer(arr, arrSize);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
reversing.c:12:3: warning: ‘arrSize’ is used uninitialized in this function [-Wuninitialized]

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.