内存错误一般都是焦聚在c和c++应用程序中,而且它会直接影响到应用程序的稳定性和正确性。这些错误都是源于程序在设计时的bug。这种错误很难重现,难于排除,并且要正确修正要花费高昂的代价。应用程序如果有内存错误定会遭受极大的问题。例如,内存泄漏会导致该应用程序耗尽内存,直接的结果是程序的异常终止。本文的主要目的是在多线程程序中理解富有挑战性的内存错误。
内存错误可以主要分为堆内存错误和栈内存错误。下面是一些主要内存错误:
1. 非法访问堆、栈内存。
2. 内存泄漏。
3. 分配和释放内存配合不当。(allocation/deallocation)
4. 忘记分配内存。
5. 访问没有初始化的堆、栈内存。
6. 越界访问内存。
非法内存访问
这个错误出现在对未分配的或已经释放的内存进行读或写的操作。
例如:
char *pStr = (char *) malloc(25);
free(pStr);
strcpy(pStr, .parallel parogarmming.); //这里就是非法对已经释放的堆内存进行写操作。
内存泄漏
内存泄漏主要是因为内存分配了但是相应的没有释放对应的内存。假如这种内存泄漏足够多的频繁发生,那么最终会引起应用程序耗尽内存,最终导致程序提前终止(异常终止)。
例如:
char *pStr = (char*) malloc(512);
return ; //只malloc,而不free
忘记分配内存
这种错误一般发生在对已经被释放的内存进行再次释放。同时也叫做重复释放或双重释放。
例如:
char* pStr = (char*) malloc(20);
free(pStr);
free(pStr); // 导致非法内存释放。
访问未初始化的内存
这种类型的内存错误主要是发生在读取没有初始化的变量在程序中。
例如:
char *pStr = (char*) malloc(512);
char c = pStr[0]; // 这里pStr的值没有初始化。
void func()
{
int a;
int b = a + 4; //读取的a没有初始化值。
}
为了避免这种错误,通常是采用在使用前(定义时)对变量进行初始化。
跨越栈内存访问
这种错误主要发生在在不同的线程中有线程访问栈内存。
例如:
main()
{
int *p;
/* ------------------- */
CreateThread(., thread #1, .); //自身拥有的栈
CreateThead(., thread #2, .);
/* -------------------- */
}
Thread #1
{
int q[1024];
p = q;
q[0] = 1;
}
Thread #2
{
*p = 2; // 栈内存跨越访问
}
最容易避免这种错误的方法是避免保存全局变量的栈地址。
By Naveen Gv
原文:http://cprogramming.com/tutorial/memory_debugging_parallel_inspector.html