出于纯粹的好奇心,我开始以我从未使用过的方式玩数组。我尝试制作数据结构数组,并将其设置为另一个数组:
typedef struct _test {
float value;
} test;
足够简单struct
,所以我尝试了这个:
test struct1[10];
test struct2[20];
struct1 = struct2;
我认为这不会起作用,甚至没有编译。但是,这让我很感兴趣。是否可以采用10的数组并将大小增加到20,同时复制数据?
目标C
我实际上是用Objective-C做的,所以我也想听听Objective-C的人。我想看看是否可以更改此文件中struct1
的大小。
@interface Object : NSObject {
test struct1;
}
记住:这只是出于好奇,所以一切都可以讨论。
答案 0 :(得分:3)
其他与您的问题不完全相关但有趣的是,虽然无法分配数组,但包含数组的结构可以分配给:
struct test
{
float someArray[100];
};
struct test s1 = { /* initialise with some data*/ };
struct test s2 = { /* initialise with some other data */ };
s1 = s2; /* s1's array now contains contents of s2's array */
这也可以从函数返回固定长度的数据数组(因为不允许返回普通数组):
struct test FunctionThatGenerates100Floats(void)
{
struct test result;
for (int i = 0; i < 100; i++)
result.someArray[i] = randomfloat();
return result;
}
答案 1 :(得分:2)
您不能在C中使用静态数组执行此操作,但您可以使用动态分配的数组执行此操作。例如,
float *struct1, *struct2, *struct3;
if(!(struct1 = malloc(10 * sizeof(float))) {
// there was an error, handle it here
}
if(!(struct2 = realloc(struct1, 20 * sizeof(float))) {
// there was an error, handle it here
// struct1 will still be valid
}
if(!(struct3 = reallocf(struct2, 40 * sizeof(float))) {
// there was an error, handle it here
// struct2 has been free'd
}
答案 2 :(得分:2)
正如其他人所说,像这样分配的数组是静态的,无法调整大小。您必须使用指针(使用malloc
或calloc
分配数组)以获得可调整大小的数组,然后您可以使用realloc
。你必须使用free
来摆脱它(否则你会泄漏内存)。在C99中,您的数组大小可以在运行时计算(在C89中,其大小必须在编译时计算),但在分配后无法更改。在C ++中,您应该使用std::vector
。我怀疑Objective-C有类似C ++的向量。
但是如果要在C中复制一个数组和另一个数组之间的数据,请使用memcpy
:
/* void *memcpy(void *dest, const void *src, size_t n)
note that the arrays must not overlap; use memmove if they do */
memcpy(&struct1, &struct2, sizeof(struct1));
当然,那只会复制前十个元素,因为struct1只有十个元素长。您可以通过将&struct2
更改为struct2+10
或&(struct2[10])
来复制最后十个(例如)。当然,在C中,不负责运行数组的末尾是你的责任:memcpy
不检查。
你也可以使用明显的for循环,但memcpy通常会更快(而且永远不会慢)。这是因为编译器可以利用它所知道的每一个技巧(例如,它可能知道如何一次复制16个字节的数据,即使每个元素只有1个字节宽)
答案 3 :(得分:1)
在C中,我相信这是使用realloc功能的好地方。但是,它只适用于动态分配的数组。没有办法通过声明struct1
更改分配给test struct1[10];
的内存。
答案 4 :(得分:1)
在C数组中是常量,你根本不能改变它们的值(即它们的地址),你也无法调整它们的大小。
答案 5 :(得分:1)
显然,如果您使用固定大小test struct1[10]
声明数组,则无法调整其大小。你需要做的是将它声明为一个指针:
test *struct1;
然后你必须使用malloc
来分配数组,并且可以使用realloc
来调整它的大小,同时保留原始数组的内容。
struct1 = malloc(10*sizeof(*struct1));
//initialize struct1 ...
test *struct2 = realloc(struct1, 20*sizeof(*struct1));
答案 6 :(得分:1)
如果你正在使用Objective C,你知道你可以使用NSMutableArray,它会自动执行realloc技巧来重新分配自己以存储你放入其中的许多对象,超出你的记忆限制。
但你是想用struct做这件事吗?这甚至意味着什么?假设您增加了Object中struct1可用的内存量。它仍然是一个包含一个成员的结构,并且不再执行任何操作。
是否要使Object能够包含扩展的结构?
typedef struct _test2 {
float value;
NSObject *reference;
} test2;
但是你仍然无法正常访问reference
,因为它不是Object的已知部分。
Object *object2;
...
NSLog(@"%@", object2.struct1.reference); // does not compile
如果你知道你有一个修改过的对象,你可以做
Object *object2;
...
NSLog(@"%@", ((test2)(object2.struct1)).reference);
而且你仍然可以将object2传递给任何需要Object的东西。如果struct1是Object的最后一个成员,它只有任何工作机会,并且不要乱用子类化Object。
然后可能会有各种各样的realloc技巧,但是我不认为realloc特别是因为它打算用于分配了malloc的对象,以及用于分配对象的C函数的细节。在Objective C中暴露,所以你不应该假设它是malloc。如果覆盖alloc
,那么您可以确保使用malloc。
此外,您必须注意这样一个事实:在Objective C中,对于存在多个对象的指针,这种情况很常见。 realloc可能会移动一个对象,除非你纠正所有指针,否则这个对象在语义上是不正确的。