在全局范围内声明动态大小的数组
Declare dynamically sized array in global scope
不经常使用 C,我遇到了一个可能很简单的问题。我有几个函数需要访问全局数组变量 g
。但是这个变量的实际大小必须在 init()
函数中定义。大小取决于其他一些东西,因此 g
必须以某种方式声明为动态大小。我阅读了 malloc
和其他功能,但我不确定如何正确使用它们。
示例:
double g[dynamic]; // size is not known yet
int n;
void init()
{
// calculate "n" for array size
n = ...
// declare and initialze g with a size "n"
}
void dostuff()
{
for (int i = 0; i < n; i++)
work(g[i]);
}
我该如何解决?
你想实现的在 C 中是不可能的。
全局数组在编译时必须具有固定大小,或者至少在 link 时。
您可以声明没有指定大小的数组:
extern double g[];
但它必须在某处定义为实际大小,由定义处的常量表达式计算得出,并且无法从上述声明中确定大小,因此必须通过其他方式将其传递给将要执行的函数使用数组:隐式地使用表示数组末尾的特殊值(如 '[=12=]'
表示 char
字符串)或通过您发布的单独变量显式使用。但是请注意,n
和 g
是全局变量的非常糟糕的名称选择,因为它们可能与局部变量名称冲突并且对 reader.
没有任何意义
如果直到 运行 时间才知道大小,您应该定义一个指针而不是数组,并且还定义一个单独的变量,其中包含将由初始化函数分配的数组长度。
double *g;
size_t g_length;
您不能使用 数组。您必须使用 指针。
double *global_array; // size is not known yet
size_t nglobal_array; // may be helpful to have the size
void init(void)
{
// calculate "nglobal_array" for array size
nglobal_array = 42;
// declare and initialze global_array with a size "nglobal_array"
global_array = malloc(nglobal_array * sizeof *global_array);
if (global_array == NULL) {
fprintf(stderr, "Error allocating resources.\nProgram aborted.\n");
exit(EXIT_FAILURE);
}
}
void dostuff()
{
for (int i = 0; i < nglobal_array; i++)
work(global_array[i]);
}
当你不再需要它时,不要忘记free(global_array)
。
完整的用法是这样的
#include <stdlib.h>
// includes
// declarations & definitions as above
int main(void) {
init();
dostuff();
free(global_array);
}
没有。 C 不会那样做。在全局范围内声明的数组已在您的二进制文件中为它们分配固定 space(Windows 上的 .EXE 文件和 Linux 上的 ELF 可执行文件)。如果你想要一个动态大小的数组,你需要动态分配它。
例子在这里:
#include <stdlib.h>
#define ARRAY_SIZE 100
typedef char T; //your type here
T* array;
void init() {
array = malloc(sizeof(T) * ARRAY_SIZE); //array filled with garbage values
//array = calloc(ARRAY_SIZE, sizeof(T)); //array filled with 0x00
}
void finish() {
free(array); // DO NOT ACCESS ARRAY AFTER THIS CALL!
}
int main() {
init();
array[6] = 63; //access array as normal
finish();
//array[41] = 23; //will most likely crash due to a segmentation fault, also called an access violation on Windoez
}
不经常使用 C,我遇到了一个可能很简单的问题。我有几个函数需要访问全局数组变量 g
。但是这个变量的实际大小必须在 init()
函数中定义。大小取决于其他一些东西,因此 g
必须以某种方式声明为动态大小。我阅读了 malloc
和其他功能,但我不确定如何正确使用它们。
示例:
double g[dynamic]; // size is not known yet
int n;
void init()
{
// calculate "n" for array size
n = ...
// declare and initialze g with a size "n"
}
void dostuff()
{
for (int i = 0; i < n; i++)
work(g[i]);
}
我该如何解决?
你想实现的在 C 中是不可能的。
全局数组在编译时必须具有固定大小,或者至少在 link 时。
您可以声明没有指定大小的数组:
extern double g[];
但它必须在某处定义为实际大小,由定义处的常量表达式计算得出,并且无法从上述声明中确定大小,因此必须通过其他方式将其传递给将要执行的函数使用数组:隐式地使用表示数组末尾的特殊值(如 '[=12=]'
表示 char
字符串)或通过您发布的单独变量显式使用。但是请注意,n
和 g
是全局变量的非常糟糕的名称选择,因为它们可能与局部变量名称冲突并且对 reader.
如果直到 运行 时间才知道大小,您应该定义一个指针而不是数组,并且还定义一个单独的变量,其中包含将由初始化函数分配的数组长度。
double *g;
size_t g_length;
您不能使用 数组。您必须使用 指针。
double *global_array; // size is not known yet
size_t nglobal_array; // may be helpful to have the size
void init(void)
{
// calculate "nglobal_array" for array size
nglobal_array = 42;
// declare and initialze global_array with a size "nglobal_array"
global_array = malloc(nglobal_array * sizeof *global_array);
if (global_array == NULL) {
fprintf(stderr, "Error allocating resources.\nProgram aborted.\n");
exit(EXIT_FAILURE);
}
}
void dostuff()
{
for (int i = 0; i < nglobal_array; i++)
work(global_array[i]);
}
当你不再需要它时,不要忘记free(global_array)
。
完整的用法是这样的
#include <stdlib.h>
// includes
// declarations & definitions as above
int main(void) {
init();
dostuff();
free(global_array);
}
没有。 C 不会那样做。在全局范围内声明的数组已在您的二进制文件中为它们分配固定 space(Windows 上的 .EXE 文件和 Linux 上的 ELF 可执行文件)。如果你想要一个动态大小的数组,你需要动态分配它。 例子在这里:
#include <stdlib.h>
#define ARRAY_SIZE 100
typedef char T; //your type here
T* array;
void init() {
array = malloc(sizeof(T) * ARRAY_SIZE); //array filled with garbage values
//array = calloc(ARRAY_SIZE, sizeof(T)); //array filled with 0x00
}
void finish() {
free(array); // DO NOT ACCESS ARRAY AFTER THIS CALL!
}
int main() {
init();
array[6] = 63; //access array as normal
finish();
//array[41] = 23; //will most likely crash due to a segmentation fault, also called an access violation on Windoez
}