在C中连接2个数组

时间:2016-10-18 04:19:31

标签: c arrays

我试图创建一个连接2个数组的函数,然后返回sum数组。 我一直在使用以下代码:

    #include "stdio.h";

struct array {
    int length;
    int *array;
};

struct array add(struct array a, struct array b) {
    int length = a.length + b.length;
    int sum[length];
    for (int i = 0; i < length; ++i) {
        if (i < a.length) {
            sum[i] = a.array[i];
        } else {
            sum[i] = b.array[i - a.length];
        }
    }

    struct array c;
    c.length = length;
    c.array = sum;
    return c;
}

int main() {
    int a[] = {1, 2, 3};
    struct array s1;
    s1.array = a;
    s1.length = sizeof(a) / sizeof(a[0]);

    int b[] = {4, 5, 6};
    struct array s2;
    s2.array = b;
    s2.length = sizeof(b) / sizeof(b[0]);

    struct array sum = add(s1, s2);
    for (int i = 0; i < sum.length; ++i) {
        printf("%d\n", sum.array[i]);
    }
    return 0;
}

输出是: 1, 17, 6356568, 1959414740, 1, 1959661600

我做错了什么?

5 个答案:

答案 0 :(得分:4)

这三行很成问题:

int sum[length];
...
c.array = sum;
return c;

首先声明 local 变量sum。在第二个中,您将c.array指向局部变量。在第三行中,当局部变量超出范围时返回指针。

由于局部变量超出范围,因此不再存在,并且指向它的指针不再有效。使用指针将导致未定义的行为

要解决此问题,您需要动态分配内存,例如malloc

答案 1 :(得分:2)

sumadd函数的局部变量。设置c.array = sum;时,指针c.array指向此局部变量。

函数返回后,本地变量被销毁。所以这个指针现在是一个悬空指针。但是在main中你会读完这个指针。

要解决此问题,您需要对程序的设计进行根本性的更改。例如,在所有情况下对struct array使用动态分配。

答案 2 :(得分:1)

C中的数组只是一个连续的内存区域,指向它们的开始*。因此合并它们涉及:

  1. 查找数组A和B的长度,(您可能需要知道元素的数量和每个元素的sizeof
  2. 分配(malloc)一个大小为A + B的新数组C.
  3. 将内存从A复制(memcpy
  4. 将内存从B复制到C +长度A(见1)。
  5. 您可能还需要取消分配(free)A和B的内存。

    示例代码段:

    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    
    #define ARRAY_CONCAT(TYPE, A, An, B, Bn) \
    (TYPE *)array_concat((const void *)(A), (An), (const void *)(B), (Bn), sizeof(TYPE));
    
    void *array_concat(const void *a, size_t an,const void *b, size_t bn, size_t s)
    {
        char *p = malloc(s * (an + bn));
        memcpy(p, a, an*s);
        memcpy(p + an*s, b, bn*s);
        return p;
    }
    
    // testing
    const int a[] = { 1, 1, 1, 1 };
    const int b[] = { 2, 2, 2, 2 };
    
    int main(void)
    {
        unsigned int i;
    
        int *total = ARRAY_CONCAT(int, a, 4, b, 4);
    
        for(i = 0; i < 8; i++)
            printf("%d\n", total[i]);
    
        free(total);
        return EXIT_SUCCCESS;
    }
    

答案 3 :(得分:0)

试试这个 - 更正add功能:

#include <stdlib.h>

struct array add(struct array a, struct array b) {
    int length = a.length + b.length;
    int * sum = (int*)calloc(length, sizeof(int));
    for (int i = 0; i < length; ++i) {
        if (i < a.length) {
            sum[i] = a.array[i];
        }
        else {
            sum[i] = b.array[i - a.length];
        }
    }

    struct array c;
    c.length = length;
    c.array = sum;
    return c;
}

stdlib需要使用calloc功能。

该函数为length类型的int值分配内存。为确保成功分配内存,建议在分配后检查指针sum的值,例如:

 int * sum = (int*)calloc(length, sizeof(int));
 if( sum != NULL )
 {
     // use memory and return result
 }
 else
 {
     // do not use pointer (report about error and stop operation)
 }

答案 4 :(得分:0)

正如Joachim所提到的,你正在返回一个局部变量int sum[length];这是一个坏主意。函数退出后,变量sum将返回到堆栈,并且可以被其他堆栈变量覆盖。

其中一种方法是首先不在sum函数中声明一个数组。 sum_str在main中声明。您可以将指向此结构的指针传递给sum函数。

更新的代码如下。

#include <stdio.h>

struct array {
    int length;
    int *array;
};

void add(struct array a, struct array b, struct array *sum_str) {
    sum_str->length = a.length + b.length;
    for (int i = 0; i < sum_str->length; ++i) {
        if (i < a.length) {
            sum_str->array[i] = a.array[i];
        } else {
            sum_str->array[i] = b.array[i - a.length];
        }
    }
}

int main() {
    int a[] = {1, 2, 3};
    struct array s1;
    s1.array = a;
    s1.length = sizeof(a) / sizeof(a[0]);

    int b[] = {4, 5, 6};
    struct array s2;
    s2.array = b;
    s2.length = sizeof(b) / sizeof(b[0]);

    struct array sum_str;
    int sum_a[6];
    sum_str.array = sum_a;

    add(s1, s2, &sum_str);
    for (int i = 0; i < sum_str.length; ++i) {
        printf("%d\n", sum_str.array[i]);
    }
    return 0;
}

另一种方法是使用动态内存分配,如其他答案所述。