在 C 中使用 `malloc` 进行动态数组连接会导致奇怪的退出代码

Using `malloc` for dynamical array concatenation in C leads to strange exit code

问题陈述

我想写一个函数

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

在纯 C 中执行以下操作:给定两个整数数组(作为指针),函数应该 return 一个新数组,它是两个输入数组的串联。

输入的名称含义如下:

我的代码

#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;
}

我的问题

作为我得到的输出,如我所愿,

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

但是,我的程序退出时退出代码为 -1073740940 而不是 0。为什么会这样?

出现意外的退出代码是因为在 C 中传递给 malloc 的输入表示 字节数 (通常不等于 数组的长度) 将在内存中分配(例如,数组中的每个 int 需要 4 个字节,而不仅仅是 1 个字节)。

因此,发生的情况是 C 为 output 数组分配的内存太少。这可以通过替换行

来解决
int *output = (int*) malloc(n1+n2);

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

现在程序将按要求退出。

这个内存分配

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

相当于

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

但是你需要为int类型的对象分配内存。那就是你需要写

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

函数声明也有问题。首先,传递的数组不会在函数内更改。所以相应的参数应该有修饰符const.

其次,指定数组中元素数量的参数应具有 size_t.

类型

第三,参数的顺序应该改变。

所以函数声明应该是这样的

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

注意要检查内存是否分配成功。当不再需要分配的数组时,您需要释放它。

此处显示了您的程序的外观。

#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 );
}