Home > Software engineering >  Using `malloc` for dynamical array concatenation in C leads to strange exit code
Using `malloc` for dynamical array concatenation in C leads to strange exit code

Time:12-29

Problem statement

I want to write a function

int *concat_tab(int n1, int *t1, int n2, int *t2)

in pure C which does the following: Given two arrays of integers (as pointers), the function should return a new array which is the concatenation of the two input arrays.

The input names mean the following:

  • n1: length of the first array;
  • *t1: pointer to the first element of the first array;
  • n2: length of the second array;
  • *t2: pointer to the first element of the second array.

My code

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

int *concat_tab(int n1, int *t1, int n2, int *t2){
    /*
     * Takes two 1D arrays and their lengths as input and outputs their concatenation.
     * Input:
     *  - n1: Length of first array
     *  - t1: First array
     *  - n2: Length of second array
     *  - t2: Second array
     * Output:
     *  - Array of length n1 n2 containing the elements of t1 followed by the elements of t2
     */
    int *output = (int*) malloc(n1 n2);
    for(int k = 0; k < n1 n2; k  ){
        if(k < n1) {
            *(output   k) = *(t1   k);
        }
        else{
            *(output   k) = *(t2 k-n1);
        }
    }
    return output;
}

int main(){
    int array1[4] = {1, 2, 3, 4};
    int array2[5] = {10, 11, 12, 13, 14};
    int *output = concat_tab(4, array1, 5, array2);
    for(int k = 0; k < 9; k  ){
        printf("Output[%d] = %d\n", k, *(output k));
    }
    return 0;
}

My problem

As output I get, as desired,

Output[0] = 1
Output[1] = 2
Output[2] = 3
Output[3] = 4
Output[4] = 10
Output[5] = 11
Output[6] = 12
Output[7] = 13
Output[8] = 14

However, my program exits with the exit code -1073740940 instead of 0. Why does that happen?

CodePudding user response:

The undesired exit code happens because the input passed to malloc in C denotes the number of bytes (which is not, in general, equal to the length of the array) that will be allocated in memory (for instance, each int in the array requires 4 bytes and not just 1).

Therefore, what happens is that C allocates too little memory for the output array. This can be fixed by replacing the line

int *output = (int*) malloc(n1 n2);

with

int *output = (int*) malloc(sizeof(int)*(n1 n2));

and now the program will exit as desired.

CodePudding user response:

This memory allocation

int *output = (int*) malloc(n1 n2);

is equivalent to

int *output = (int*) malloc( ( n1 n2 ) * sizeof( char ));

But you need to allocate memory for objects of the type int. That is you need to write

int *output = (int*) malloc( ( n1 n2 ) * sizeof( int ) );

Also the function declaration is bad. Firstly the passed arrays are not being changed within the function. So the corresponding parameters should have the qualifier const.

Secondly the parameters that specify the number of elements in the arrays should have the type size_t.

Thirdly the order of parameters should be changed.

So the function declaration should look like

int * concat_tab( const int *t1, size_t n1, const int *t2, size_t n2 );

Pay attention to that you should to check whether the memory was allocated successfully. And you need to free it when the allocated array is not required any more.

Here is shown how your program can look.

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

int * concat_tab( const int *t1, size_t n1, const int *t2, size_t n2 )
{
    int *output = NULL;

    if (n1 || n2)
    {
        output = malloc( ( n1   n2 ) * sizeof( int ) );

        if (output != NULL)
        {
            memcpy( output, t1, n1 * sizeof( int ) );
            memcpy( output   n1, t2, n2 * sizeof( int ) );
        }
    }

    return output;
}

int main( void )
{
    int array1[] = { 1, 2, 3, 4 };
    size_t n1 = sizeof( array1 ) / sizeof( *array1 );

    int array2[] = { 10, 11, 12, 13, 14 };
    size_t n2 = sizeof( array2 ) / sizeof( *array2 );

    int *output = concat_tab( array1, n1, array2, n2 );

    if ( output != NULL )
    {
        for (size_t i = 0; i < n1   n2; i  )
        {
            printf( "Output[%zu] = %d\n", i, *( output   i ) );
        }
    }

    free( output );
}
  • Related