您的位置:首页 > 其它

简单的多线程(活用OD解决运行时错误)

2016-02-24 19:56 281 查看
代码源自《VC++深入详解》第15章 “多线程”,位于第563页 - 566 页。

程序的目的是展示多线程运行的效果:

#include <windows.h>
#include <iostream.h>

DWORD WINAPI Fun1Proc(
LPVOID lpParameter   // thread data
);

int index = 0;

int main()
{
HANDLE hThread1;
hThread1 = CreateThread( NULL,0,Fun1Proc,NULL,0,NULL );
CloseHandle( hThread1 );
while ( index++ < 1000 )
cout << "main thread is running." << endl;

return 0;
}

DWORD WINAPI Fun1Proc(
LPVOID lpParameter   // thread data
)
{
while ( index++ < 1000 )
cout << "thread1 is running" << endl;

return 0;
}


运行时却发现程序崩溃了:



单击取消用OD调试:



发现程序是因为读一个0地址的内存引发了异常。在VC6中F5调试程序:





黄箭头指向的代码中对指针p解引用,而p的的值为0,这引发了异常。右击打开文件的属性,查看文件名:



是一个C语言文件,文件名为WRITE,写入的意思。我们的程序什么操作用到了写入呢?没错!用到了cout向屏幕输出字符串。

将#include 语句改为标准格式:

#include <windows.h>
#include <iostream>

using namespace std;

DWORD WINAPI Fun1Proc(
LPVOID lpParameter   // thread data
);

int index = 0;

int main()
{
HANDLE hThread1;
hThread1 = CreateThread( NULL,0,Fun1Proc,NULL,0,NULL );
CloseHandle( hThread1 );
while ( index++ < 1000 )
cout << "main thread is running." << endl;

return 0;
}

DWORD WINAPI Fun1Proc(
LPVOID lpParameter   // thread data
)
{
while ( index++ < 1000 )
cout << "thread1 is running" << endl;

return 0;
}


就可以完美运行:



然而,这是为什么呢?我们只是猜到出问题的地址,并不了解其中的原理。尝试着百度一下:


iostream.h与iostream是不同的。
#include<iostream.h>是在旧的标准C++中使用。在新标准中,用#include<iostream>。iostream的意思是输入输出流。#include<iostream>是标准的C++头文件,任何符合标准的C++开发环境都有这个头文件。还要注意的是:在VC编程时要添加:
using namespace std;
其原因是:后缀为.h的头文件C++标准已经明确提出不支持了,早些的实现将标准库功能定义在全局空间里,声明在带.h后缀的头文件里,C++标准为了和C区别开,也为了正确使用命名空间,规定头文件不使用后缀.h。因此,当使用<iostream.h>时,相当于在C中调用库函数,使用的是全局命名空间,也就是早期的C++实现;当使用<iostream>的时候,该头文件没有定义全局命名空间,必须使用namespace std;这样才能正确使用cout。

关系

<string.h>是旧的C头文件,对应的是基于char*的字符串处理函数;<string>是包装了std的C++头文件,对应的是新的string类;<cstring>是对应旧的C头文件的std版本。而<iostream.h>和<iostream>的关系,类似于<string.h>和<cstring>的关系,实现的功能是相同的,主要是是否使用命名空间std的区别。

原因就是我们使用了C++标准不支持的.h头文件,而其中的处理函数则是C语言编写的,这样基于char*的处理函数在多线程时很可能出现大问题,还是用<iostream>比较安全,也比较符合标准。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: