C中的基本数组用法?

时间:2011-04-19 04:34:53

标签: c arrays segmentation-fault

这是你们如何获得ANSI-C99数组的大小?看起来有点笨拙,来自高级语言。

int tests[7];
for (int i=0; i<sizeof(tests)/sizeof(int); i++) {
    tests[i] = rand();
}

此分段也出现故障。

int r = 10000000;
printf ("r: %i\n", r);
int tests[r];

运行它:

r: 10000000
Segmentation fault

10000000段故障,但1000000工作。

如何从中获取更多信息?我应该检查什么以及如何调试这样的东西? C阵列有限制吗?什么是分段错误?

6 个答案:

答案 0 :(得分:3)

在C中获取数组的大小很容易。这将为您提供以字节为单位的数组大小。

sizeof(x)

但我想你需要的是元素数量,在这种情况下它将是:

sizeof(x) / sizeof(x[0])

您可以为此编写一个简单的宏:

#define NumElements(x)  (sizeof(x) / sizeof(x[0]))

例如:

int a[10];
int size_a = sizeof(a); /* size in bytes */
int numElm = NumElements(a); /* number of elements, here 10 */

答案 1 :(得分:2)

为什么要计算尺寸?

定义一个包含大小的常量,并在声明数组时使用它。只要你想要数组的大小,就引用常量。

作为一名主要的C ++程序员,我会说历史上常量通常被定义为枚举值或#define。在C中,这可能是当前而不是历史 - 但我不知道当前C如何处理“const”。

如果您真的想要计算大小,请定义一个宏来执行此操作。甚至可能有一个标准的。

段错误的原因很可能是因为您尝试声明的数组大约为40兆字节,并被声明为局部变量。大多数操作系统限制堆栈的大小。将您的阵列保留在堆上或全局内存中,对于大多数系统而言,一个变量的40兆字节可能是正常的,尽管某些嵌入式系统可能仍然会犯规。在像Java这样的语言中,所有对象都在堆上,并且只有引用保留在堆栈中。这是一个简单而灵活的系统,但通常比在堆栈上存储数据效率低得多(堆分配开销,可避免的堆碎片,间接访问开销......)。

答案 2 :(得分:1)

传统上,数组具有静态大小。所以我们可以做到

#define LEN 10
int arr[LEN];

但不是

int len;
scanf("%d", &len);
int arr[len]; // bad!

由于我们在编译时知道数组的大小,因此获取数组的大小往往是微不足道的。我们不需要sizeof,因为我们可以通过查看声明来确定大小。

C ++提供堆数组,如

int len;
scanf("%d", &len);
int *arr = new int[len];

但由于这涉及指针而不是堆栈数组,我们必须将大小存储在我们手动传递的变量中。

答案 3 :(得分:1)

C中的数组不知道它们有多大,所以是的,您必须使用sizeof array / sizeof array[0]技巧来获取数组中的元素数量。

至于段错误问题,我猜测你通过尝试分配10000000 * sizeof int字节来超出堆栈大小。根据经验,如果您需要超过几百个字节,请使用malloccalloc动态分配,而不是尝试创建大型auto变量:

int r = 10000000;
int *tests = malloc(sizeof *test * r);

请注意,在大多数情况下,您可以将tests 视为它是一种数组类型(也就是说,您可以将其下标,您可以将其传递给任何需要数组的函数,等),但不是数组类型;它是一个指针类型,因此sizeof tests / sizeof tests[0]技巧不起作用。

答案 4 :(得分:0)

Stack Overflow!尝试在堆上而不是堆栈上进行分配。

答案 5 :(得分:0)

我怀疑是因为整数溢出。尝试使用printf打印值:

printf("%d", 10000000);

如果它打印一个负数 - 这就是问题。