2017-07-05 28 views
1

我試圖使用函數將數組連接在一起。它以某種方式工作,但會提示錯誤中止陷阱6.另外,它還說我無法釋放分配的內存。中止陷阱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; 
} 
+5

'表= ARR1;'有效地使你的程序中前行就忘了全新的分配的內存位置... –

+0

只是打敗了我 - 你需要將所有3個數組的值複製到'table'中。該分配不會執行表副本。 –

+0

只是fyi,你可以得到你的數組中的元素數量,並用(例如)sizeof(a1)/ sizeof(a1 [0])替換幻數 – yano

回答

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

'''','tableLen'和'tableOffset'應該有'unsigned int'類型。一個更好的選擇是將所有這些大小和索引值設置爲size_t。 – chqrlie

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