2015-09-06 68 views
0

我正在通过K & R练习1-13工作,并且我忘记将数组中的元素设置为0.令我惊讶的是,打印数组是32767;随后的测试对阵列有不同的元素值,有些不同,有些则不是。在C中初始化int数组而不指定值

我想知道为什么会发生这种情况。如果它非常复杂,那么简单来说会发生什么?

#include <stdio.h> 

#define IN 1 /* inside a word */ 
#define OUT 0 /* outside a word */ 

/* print the length of words as input to a histogram with horizontal bars */ 
int main() { 
    int c, i; 
    int state = OUT; 
    int accum = 0; 
    int nchar[10]; 

    while ((c = getchar()) != EOF) { 
    if (c != ' ' && c != '\n' && c != '\t') { 
     state = IN; 
     ++accum; 
    } 
    else { 
     state = OUT; 
     ++nchar[accum]; 
     accum = 0; 
    } 
    } 
    for (i = 0; i < 10; ++i) 
    printf("%d\n", nchar[i]); 
    return 0; 
} 

输入&相应的输出:

hello codes 

4195584 
0 
0 
0 
4196032 
2 
4195584 
0 
-1608045280 
32767 
+3

它被称为“未定义的行为”。没有人设置任何数组值,所以你永远不能说将会发生什么,虽然有时候它可能是可预测的。 –

+1

我更担心你使用'accum'。你从不检查它何时达到数组限制。值'0'..'9'确定,然后在极端情况下,您可能需要取消计算机,因为将'nchar'索引10非常糟糕。 while((c = getchar())!= EOF && accum <10){' –

回答

1

创建数组时,编译器会声明堆栈上的内存。如果您正在初始化数组或(通常)为其分配值,则数据将写入该内存位置。

如果您没有初始化任何内容,只声称内存,这是之前已经使用过的其他内容。在数据被移除后,堆栈不会清零,因为它会浪费太多的处理器时间,并且无论如何RAM都会被重新填充。

1

这只是当你不初始化内存会发生什么。你得到什么之前你的程序声称它...

+0

如何确定将使用哪个内存? –

+2

这主要取决于操作系统,但通常情况下,你不能假设你将得到什么。 – Amit

+2

由于堆栈的工作方式,您通常会因为已超出作用域而不再存在的变量(如完成的函数调用的局部变量)而以旧值结束。如果你不走运,你可能会“幸运”并“继承”一个适合你的初始值 - 直到代码中其他不相关部分的改变破坏了所有内容。像这样的错误可能很难找到(但'valgrind'工具可以帮助你很多)。 –

1

无论以前在你的地址空间中运行的程序放在那里。所以,如果一个程序把,比如说,77,地址0xabcd5657,然后你看的地址,你会得到77.这是因为C为你所做不是零初始化的内存,但你可以自己用memset

memset(nchar, 0, 10);