多线程里一句代码出错,请高手大侠看看
错误提示:
Project test.exe raised exception class EAcessViolation with message
Access violation at address 0041A88D.
Read of address 00000000.
Unit_GetMacAndName.cpp文件如下://---------------------------------------#include <vcl.h>#pragma hdrstop#include "Unit_GetMacAndName.h"#include <stdio.h>#include <stdlib.h>#include <Winsock.h>#include <iphlpapi.h>#include <nb30.h>#pragma package(smart_init)//---------------------------------------// Important: Methods and properties of objects in VCL can only be// used in a method called using Synchronize, for example://// Synchronize(UpdateCaption);//// where UpdateCaption could look like://// void __fastcall TGetMacAndName::UpdateCaption()// {// Form1->Caption = "Updated in a thread";// }//---------------------------------------//---------------------------------------__fastcall TGetMacAndName::TGetMacAndName(bool CreateSuspended) : TThread(CreateSuspended){ PeekMessage(&msg,0,0,0,PM_NOREMOVE); FreeOnTerminate = true; success_ip = new char[16]; //192.168.111.222 hostname = new char[50]; mac = new char[20];}//---------------------------------------__fastcall TGetMacAndName::~TGetMacAndName(){ delete success_ip; delete hostname; delete mac;}//---------------------------------------void __fastcall TGetMacAndName::Execute(){ //---- Place thread code here ---- WSADATA wsaData; int iRet = WSAStartup(MAKEWORD(2,1), &wsaData); if ( iRet != 0 ) { return; } hostent * remoteHostent = (hostent*)malloc(sizeof(hostent)); int nRemoteAddr ; NCB Ncb; UCHAR uRetCode; LANA_ENUM lenum; typedef struct _ASTAT_ { ADAPTER_STATUS adapt; NAME_BUFFER NameBuf[30]; }ASTAT,* PASTAT; ASTAT Adapter; CoInitialize(NULL); while( !Suspended || !Terminated ) { if( GetMessage(&msg,0,0,0) ) { switch(msg.message) { case MY_MSG_MAC: memset( success_ip, 0, strlen(success_ip)+1 ); memcpy( success_ip, (char *)msg.lParam, strlen((char *)msg.lParam)+1 ); if( AnsiString(success_ip) != "" ) { try { //获取远程机器名 nRemoteAddr = inet_addr( success_ip ); //传入IP remoteHostent = gethostbyaddr( (char*)&nRemoteAddr,sizeof(in_addr),AF_INET ); //strcpy( hostname, remoteHostent->h_name ); memset( hostname, 0, strlen(hostname)+1 ); [color=#FF0000]memcpy( hostname, remoteHostent->h_name, strlen(remoteHostent->h_name)+1 );//这句出错。[/color] //获取远程机器MAC memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBENUM; Ncb.ncb_buffer = (UCHAR *)&lenum; Ncb.ncb_length = sizeof(lenum); uRetCode = Netbios( &Ncb ); for( int J=0;J<lenum.length;J++) { memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBRESET; Ncb.ncb_lana_num = lenum.lana[J]; uRetCode = Netbios( &Ncb ); memset(&Ncb, 0, sizeof(Ncb)); Ncb.ncb_command = NCBASTAT; Ncb.ncb_lana_num = lenum.lana[J]; strcpy( (char *)Ncb.ncb_callname, success_ip );//传入IP地址 Ncb.ncb_buffer = (unsigned char *) &Adapter; Ncb.ncb_length = sizeof(Adapter); uRetCode = Netbios( &Ncb ); if (uRetCode == 0) { char buf[100]; wsprintf( buf,"%02x-%02x-%02x-%02x-%02x-%02x", Adapter.adapt.adapter_address[0], Adapter.adapt.adapter_address[1], Adapter.adapt.adapter_address[2], Adapter.adapt.adapter_address[3], Adapter.adapt.adapter_address[4], Adapter.adapt.adapter_address[5] ); //strcpy( mac, buf ); memset( mac, 0, strlen(mac)+1 ); memcpy( mac, buf, strlen(buf)+1 ); } } } catch(...) { } } } } } WSACleanup();}//---------------------------------------Unit_GetMacAndName.h文件如下://---------------------------------------#ifndef Unit_GetMacAndNameH#define Unit_GetMacAndNameH//---------------------------------------#include <Classes.hpp>//---------------------------------------class TGetMacAndName : public TThread{ private:protected: void __fastcall Execute();public: __fastcall TGetMacAndName(bool CreateSuspended); MSG msg; char * success_ip; char * hostname; char * mac; __fastcall ~TGetMacAndName(); };//---------------------------------------#endif
//从这个程序看滥用指针,success_ip等直接定义成数组更好! delete success_ip; //=>delete[] success_ip; delete hostname; //=>delete[] hostname; delete mac; //=>delete[] mac;hostent * remoteHostent = (hostent*)malloc(sizeof(hostent)); //这儿的内存分配是多于的,会造成内存泄漏。remoteHostent = gethostbyaddr( (char*)&nRemoteAddr,sizeof(in_addr),AF_INET );//看来你的gethostbyaddr返回了NULL!
[解决办法]
楼上们的大虾们,已经都指出你的问题了
给你汇总一下:
1、new数组 删除要 delete []
例:hostname = new char[50];
delete hostname; //=>delete[] hostname;
2、gethostbyaddr()返回要先检测是否成功
帮助里说明:If no error occurs, gethostbyaddr returns a pointer to the hostent structure. Otherwise, it returns a null pointer
addr = inet_addr(host_addr);
remoteHost = gethostbyaddr((char *) &addr, 4, AF_INET);
if(remoteHost!=NULL)
{
}
3、
memset( hostname, 0, strlen(hostname)+1 );
strlen(hostname)+1=???
你好像是new char[50]
那这里直接改为memset( hostname, 0, 50 );
4、
memcpy( hostname, remoteHostent->h_name, strlen(remoteHostent->h_name) );
hostname[strlen(remoteHostent->h_name)]='\0';