我用C / C ++编写代码。有哪些方法可以破坏存储在数据段中的静态变量?这被认为是内存泄漏吗?
#include <stdio.h>
int aaa[5];
int bbb;
int main()
{
int i;
bbb=41;
for (i = 0; i < 6; ++i)
aaa[i] = 42;
printf("%d\n", bbb);
return 0;
}
上面的代码打印bbb = 42而不是41.这是一个可能的原因。另一种方法是修改 通过多个线程访问的静态数据。
还有其他方法吗?
答案 0 :(得分:4)
不,这不是内存泄漏。内存泄漏是指您在免费商店(使用malloc
/ new
)分配,然后永远不会free
/ delete
分配的块。
答案 1 :(得分:2)
请注意,这是未定义的行为,无法保证:
int bbb;
int aaa[5];
int main()
{
int i;
bbb=41;
for (i = 0; i < 6; ++i)
aaa[i] = 42;
printf("%d\n", bbb);
return 0;
}
g++ -o test test.cpp && ./test
41
在这种特殊情况下,bbb存储在aaa之后,但你根本不应该依赖它,因为它可能在其他地方。
答案 2 :(得分:1)
所有全局变量(静态或其他)在执行过程中的任何代码之前被加载器初始化为其声明中指定的值(如果未指定则为零)。默认值只能由进程内执行的代码修改(除非来自调试器的任何外部干扰)。
如果您在程序的main()
函数开头看到“损坏”值,则很可能是由于在全局C ++对象的构造函数中执行了错误操作。所有全局C ++对象的构造函数都在调用main()
之前运行。
追踪此类损坏源的最简单方法可能是在调试器下运行该进程,并在全局变量的地址上设置一个观察点。修改数据时,调试器将中断。可能有阵列溢出或错误指针问题。它们可能是手动追踪的婊子。
答案 3 :(得分:1)
是的,有多种方法可以销毁全局变量的内容(您的变量在您发布的示例中不是静态的)。
指针是破坏内存并写入程序不应该写入的好工具。施法也会增加一些兴奋感:
#include <iostream>
using namespace std;
int aaa[5];
int bbb;
int main(void) // Do *your* main() functions always return a value????
{
double * ptr_double = 0;
// Assign the pointer to double to point to the last integer.
// Treat the last integer in the array as a double.
aaa[4] = 45;
cout << "aaa[4] = " << aaa[4] << endl;
ptr_double = (double *)(&aaa[4]);
*ptr_double = 3.14159267;
cout << "aaa[4] = " << aaa[4] << endl;
return -1;
}
使用多个线程,您可以让每个线程写入全局变量,然后让它们读回值。在写作之前和写入之后放置随机延迟可以更详细地向您展示它是如何工作的。
另一种方法是将变量的地址分配给I / O硬件设备的目标寄存器,如UART。当UART接收数据时,它会将该数据放在该变量中,而不考虑变量的用途。
通常,代码写入不应该写入的位置会损坏值。主要原因是缓冲区溢出:写入的数据多于为变量分配的数据。超出也可能来自硬件设备,如DMA控制器和USB控制器。另一个原因是通过指针:指针指向无效的位置。
变量可能会被Stack Overflows和Heap Overflows损坏。在许多架构中,这些结构相互扩展。堆栈上的变量太多,或者函数递归(或调用深度)会使堆栈覆盖到堆中。同样,从堆中分配太多内存可能会使堆覆盖堆栈。
我认为您应该努力提高代码安全性,而不是探索如何破坏变量:设计和编写代码使其没有缓冲区溢出,正确位置的写入和共享变量受到多个任务和线程的同时写入保护
答案 4 :(得分:1)
这是典型的编程错误。 在使用6个aaa时定义aaa数组的5个项目,这意味着你只能使用aaa [0],aaa [1],aaa [2],aaa [3]和aaa [4]。 aaa [5]未定义。 这是一个错误,一个编程错误,没有别的。周期。