在 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 一个新数组,它是两个输入数组的串联。
输入的名称含义如下:
n1
:第一个数组的长度;
*t1
:指向第一个数组第一个元素的指针;
n2
:第二个数组的长度;
*t2
:指向第二个数组第一个元素的指针。
我的代码
#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 );
}
问题陈述
我想写一个函数
int *concat_tab(int n1, int *t1, int n2, int *t2)
在纯 C 中执行以下操作:给定两个整数数组(作为指针),函数应该 return 一个新数组,它是两个输入数组的串联。
输入的名称含义如下:
n1
:第一个数组的长度;*t1
:指向第一个数组第一个元素的指针;n2
:第二个数组的长度;*t2
:指向第二个数组第一个元素的指针。
我的代码
#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 );
}