为什么内存位置被分配垃圾值?
Why are memory locations assigned garbage values?
我一直想知道为什么内存中存储的是垃圾值space。为什么内存不能用零填充。有什么特别的原因吗?
例如:
int a ;
cout<<a //garbage value displayed
现代操作系统会在您的进程首次访问内存之前将内存初始化为 0。但是一旦它被使用一次,除非有特殊需要,否则通常没有必要再次将其归零。 "garbage values" 就是最后写入该内存的内容。
因为清除内存(或者肯定是)很昂贵,而且在大量常见情况下不需要它。
在示例中,您显示的是堆栈内存。每次都将其清零将非常昂贵(基本上每个函数调用都必须清除一块内存)。
出于(主要是历史的)性能原因。将稍后分配适当值的内存位置清零是不必要的工作,c/c++ 口号之一是 "You don't pay for what you don't need"。
通常你应该总是在声明变量时正确地初始化它,但尤其是在 c 中,你有时只是不知道变量的初始值应该是多少。
编辑:如果您的问题是关于垃圾数据的来源:它只是以前存储在同一物理地址的数据。比方说,您正在一个接一个地调用以下两个函数:
void foo(){
int a=5;
}
void foo2() {
int b;
std::cout << b << std::endl;
}
int main() {
foo1();
foo2();
}
很有可能(在调试模式下)程序的输出为 5(我相信,这实际上是 UB,所以 - 考虑到编译器优化 - 当然,任何事情都可能发生)
分配零需要时间,而且并不总是程序员想要做的。考虑一下:
int a;
std::cin >> a;
当您要做的第一件事是在内存中存储一个不同的值时,为什么要浪费时间将零加载到内存中?
您得到的垃圾值是以前存储在该地址中的值。但在 C++(和许多其他语言)中,将它们全部初始化为零是一项相当昂贵的任务,编译器不会这样做。这会浪费编译器本可以用于其他目的的大量时间。因此,分配新值不是由编译器完成的。
但也有其他编译器将它们初始化为 0,但 C++ 不是其中之一。
通常,编译器会期望您为新变量赋予新值。喜欢
int a = 0; // this is not so hard to do
或
int a;
std::cin >> a ;
所以,我们赋值比编译器初始化然后覆盖它要高效得多。
如果你在访问它们之前不给它们赋值,编译器会给你一个关于未初始化变量的警告。 (如果您打开了编译器警告)。
垃圾值来自内存中存在的内容 space。在您的情况下,您只声明了变量而没有初始化它。声明变量但未初始化时,会为该变量分配内存但不会清除,主要是出于性能原因。因此,它可能包含一个您不希望它包含的初始值,这可能有多种原因。根据Code Complete第10章,有几个原因包括:
- 该变量从未被赋值。它的值是程序启动时恰好在其内存区域中的任何位。
- 变量中的值已过时。变量在某个时候被赋值,但该值不再有效。
- 部分变量已赋值,部分未赋值(具体涉及到可能有多个数据成员的对象)。
一个好的做法是在尽可能靠近变量首次使用的位置声明和初始化变量,即通过将相关操作放在一起来遵循邻近原则。
我一直想知道为什么内存中存储的是垃圾值space。为什么内存不能用零填充。有什么特别的原因吗?
例如:
int a ;
cout<<a //garbage value displayed
现代操作系统会在您的进程首次访问内存之前将内存初始化为 0。但是一旦它被使用一次,除非有特殊需要,否则通常没有必要再次将其归零。 "garbage values" 就是最后写入该内存的内容。
因为清除内存(或者肯定是)很昂贵,而且在大量常见情况下不需要它。
在示例中,您显示的是堆栈内存。每次都将其清零将非常昂贵(基本上每个函数调用都必须清除一块内存)。
出于(主要是历史的)性能原因。将稍后分配适当值的内存位置清零是不必要的工作,c/c++ 口号之一是 "You don't pay for what you don't need"。
通常你应该总是在声明变量时正确地初始化它,但尤其是在 c 中,你有时只是不知道变量的初始值应该是多少。
编辑:如果您的问题是关于垃圾数据的来源:它只是以前存储在同一物理地址的数据。比方说,您正在一个接一个地调用以下两个函数:
void foo(){
int a=5;
}
void foo2() {
int b;
std::cout << b << std::endl;
}
int main() {
foo1();
foo2();
}
很有可能(在调试模式下)程序的输出为 5(我相信,这实际上是 UB,所以 - 考虑到编译器优化 - 当然,任何事情都可能发生)
分配零需要时间,而且并不总是程序员想要做的。考虑一下:
int a;
std::cin >> a;
当您要做的第一件事是在内存中存储一个不同的值时,为什么要浪费时间将零加载到内存中?
您得到的垃圾值是以前存储在该地址中的值。但在 C++(和许多其他语言)中,将它们全部初始化为零是一项相当昂贵的任务,编译器不会这样做。这会浪费编译器本可以用于其他目的的大量时间。因此,分配新值不是由编译器完成的。
但也有其他编译器将它们初始化为 0,但 C++ 不是其中之一。
通常,编译器会期望您为新变量赋予新值。喜欢
int a = 0; // this is not so hard to do
或
int a;
std::cin >> a ;
所以,我们赋值比编译器初始化然后覆盖它要高效得多。
如果你在访问它们之前不给它们赋值,编译器会给你一个关于未初始化变量的警告。 (如果您打开了编译器警告)。
垃圾值来自内存中存在的内容 space。在您的情况下,您只声明了变量而没有初始化它。声明变量但未初始化时,会为该变量分配内存但不会清除,主要是出于性能原因。因此,它可能包含一个您不希望它包含的初始值,这可能有多种原因。根据Code Complete第10章,有几个原因包括:
- 该变量从未被赋值。它的值是程序启动时恰好在其内存区域中的任何位。
- 变量中的值已过时。变量在某个时候被赋值,但该值不再有效。
- 部分变量已赋值,部分未赋值(具体涉及到可能有多个数据成员的对象)。
一个好的做法是在尽可能靠近变量首次使用的位置声明和初始化变量,即通过将相关操作放在一起来遵循邻近原则。