我试图创建一个连接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
我做错了什么?
答案 0 :(得分:4)
这三行很成问题:
int sum[length];
...
c.array = sum;
return c;
首先声明 local 变量sum
。在第二个中,您将c.array
指向局部变量。在第三行中,当局部变量超出范围时返回指针。
由于局部变量超出范围,因此不再存在,并且指向它的指针不再有效。使用指针将导致未定义的行为。
要解决此问题,您需要动态分配内存,例如malloc
。
答案 1 :(得分:2)
sum
是add
函数的局部变量。设置c.array = sum;
时,指针c.array
指向此局部变量。
函数返回后,本地变量被销毁。所以这个指针现在是一个悬空指针。但是在main
中你会读完这个指针。
要解决此问题,您需要对程序的设计进行根本性的更改。例如,在所有情况下对struct array
使用动态分配。
答案 2 :(得分:1)
C中的数组只是一个连续的内存区域,指向它们的开始*。因此合并它们涉及:
sizeof
)malloc
)一个大小为A + B的新数组C. memcpy
,您可能还需要取消分配(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;
}
另一种方法是使用动态内存分配,如其他答案所述。