在阵列连接功能中中止陷阱6

时间:2017-07-05 21:56:11

标签: c

我正在尝试使用函数将数组连接在一起。它以某种方式工作,但提示错误中止陷阱6.此外,它还说我无法释放分配的内存。

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

int *join_arrays(unsigned int arr1N, int arr1[], unsigned int arr2N, int arr2[], unsigned int arr3N, int arr3[]) {
  int tableLen = arr1N + arr2N + arr3N;
  printf("%d\n", tableLen);
  int *table = malloc(tableLen * sizeof(int));
  table = arr1;
  printf("%d\n", table[arr1N - 1]);
  for (int i = 0; i < arr2N; i++) {
   table[i + arr1N] = arr2[i];
  }
  printf("%d\n", table[arr1N + arr2N - 1]);
  for (int j = 0; j < arr3N; j++) {
   table[j + arr1N + arr2N] = arr3[j];
  }

  return table;
}

int main(void)
{
    int a1[] = { 89, 53, 98, 5, 5, 49, 95, 9, 54, 59, 59 };
    int a2[] = { 44, 25, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 144, 0, 0, 0, 0};
    int a3[] = { 20, 21, 22 };

    int *joined = join_arrays(11, a1, 17, a2, 3, a3);

    for (int i = 0; i < 11 + 17 + 3; i++) {
        printf("%d  ", joined[i]);
    }
    printf("\n");

    free(joined);

    return 0;
}

2 个答案:

答案 0 :(得分:1)

请注意,您需要复制所有3个表,而不仅仅是第二个和第三个表。表的分配实际上会丢弃动态内存指针:

int *join_arrays(unsigned int arr1N, int arr1[], unsigned int arr2N, int arr2[], unsigned int arr3N, int arr3[]) {
  int tableLen = arr1N + arr2N + arr3N;
  printf("%d\n", tableLen);
  int *table = malloc(tableLen * sizeof(int));
  int tableOffset = 0;

  for (int i = 0; i < arr1N; i++) {
   table[tableOffset++] = arr1[i];
  }

  for (int i = 0; i < arr2N; i++) {
   table[tableOffset++] = arr2[i];
  }

  for (int i = 0; i < arr3N; i++) {
   table[tableOffset++] = arr3[i];
  }

  return table;
}

我还考虑作为参数返回,以便也可以返回数组长度。为了获得更高的性能,使用memcpy()也可能对某些系统有所帮助,但是对于这样一个简单的例子,for循环更容易理解。

答案 1 :(得分:1)

功能错误。至少存在内存泄漏。首先,指针table指向已分配的内存,但随后重新分配并指向传递给函数的第一个数组的第一个字符作为参数。

int *table = malloc(tableLen * sizeof(int));
table = arr1;

因此函数中使用的两个循环尝试复制到第一个数组,因此它们访问数组之外​​的内存。

考虑到更改函数参数的顺序要好得多。首先应该指定一个数组,然后才能指定它的大小。此外,数组应使用限定符const声明,并且其大小应为size_t类型。

使用像11,17和3这样的幻数也是一个坏主意。通常这样的用法是程序错误的原因。

您可以使用标准C函数memcpy代替循环。

程序可以按以下方式查看

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

int * join_arrays( const int a1[], size_t n1, 
                   const int a2[], size_t n2, 
                   const int a3[], size_t n3 ) 
{
    int *joined = malloc( ( n1 + n2 + n3 ) * sizeof( int ) );

    if ( joined != NULL )
    {
        memcpy( joined, a1, n1 * sizeof( int ) );       
        memcpy( joined + n1, a2, n2 * sizeof( int ) );      
        memcpy( joined + n1 + n2, a3, n3 * sizeof( int ) );     
    }

    return joined;
}

int main( void ) 
{
    int a1[] = { 89, 53, 98, 5, 5, 49, 95, 9, 54, 59, 59 };
    int a2[] = { 44, 25, 0, 0, 0, 0, 0, 0, 0, 0, 80, 0, 144, 0, 0, 0, 0};
    int a3[] = { 20, 21, 22 };

    size_t n1 = sizeof( a1 ) / sizeof( *a1 );
    size_t n2 = sizeof( a2 ) / sizeof( *a2 );
    size_t n3 = sizeof( a3 ) / sizeof( *a3 );

    int *joined = join_arrays( a1, n1, a2, n2, a3, n3 );

    if ( joined != NULL )
    {
        for ( size_t i = 0, n = n1 + n2 + n3; i < n; i++ ) 
        {
            printf( "%d  ", joined[i] );
        }
        printf( "\n" );
    }


    free( joined );

    return 0;
}

它的输出是

89  53  98  5  5  49  95  9  54  59  59  44  25  0  0  0  0  0  0  0  0  80  0  144  0  0  0  0  20  21  22