1

I'm very new to C++ but have made a console application that waits until it detects a window with a certain title and then executes some code. It's working really well as long as it detects a window. However, I've noticed that if the application is run and the window doesn't appear then, after 4 minutes and 20 seconds (approx.) it crashes.

The crash information simply says APPCRASH attributed to ntdll.dll

I've put breakpoints in the code and narrowed it down to this piece of code that is causing the crash.

// GRAB WINDOW TITLE AND PUT IT IN "lpszTitle"
int nLen = GetWindowTextLength(hWnd);
LPSTR lpszTitle = new CHAR[nLen + 1];
GetWindowText(hWnd, lpszTitle, nLen);

This code is followed by an "if" statement that executes the main code when the window title matches a certain string.

Until then, this code just runs on a while(1) loop waiting.

Here is a more complete listing of the code.

#pragma once
#undef UNICODE
#include <windows.h>
#include <iostream>
#include <string>
#include <sstream>
#include <tchar.h>
#include <cassert>
#include <cstdio>
#include <stdlib.h>
#include <mmsystem.h>
#include <time.h>


// Example of the __stdcall keyword  
#define WINAPI __stdcall

using namespace std;

HMODULE hLib;
BOOL CALLBACK SearchProc(HWND hWnd, LPARAM lParam)
{

// THIS FUNCTION SEARCHES ALL OPEN WINDOWS
// UNTIL IT FINDS ONE WITH "DX" IN IT'S TITLE
// IT THEN GRABS THE MEMORY ADDRESS REFERENCED
// BELOW WHICH CONTAINS THE "TOTALOUT" VARIABLE
// FOR THE FRUIT MACHINE




// INITIALISE VARIABLES FOR USE IN THIS FUNCTION
DWORD address = 0x96e0a4;
long currentMachinePaidOutTotal = 0;
long unsortedTotalcurrentMachinePaidOutTotal = 0;
long calculatedWinnings = 0;    
long oldAmountMachinePaidOut = 0;
bool initialiseOldAmountMachinePaidOut = false;
bool slowMachine = false;
bool payoutFiverOneShot = false;
string currentWindowName = "";
DWORD pid;

// GRAB WINDOW TITLE AND PUT IT IN "lpszTitle"
int nLen = GetWindowTextLength(hWnd);
LPSTR lpszTitle = new CHAR[nLen + 1];
GetWindowText(hWnd, lpszTitle, nLen);


// LET'S CHECK IF WINDOW HAS "DX" IN TITLE
if (strstr(lpszTitle, "DX") && !strstr(lpszTitle, "=")) {
    cout << "\nFound window with name: " << lpszTitle << "\n";
    currentWindowName = lpszTitle;

    // Found "DX" in the title of the window
    // CONTINUE WITH CODE IN HERE....

    return TRUE;
}
else {
    // NO WINDOW WITH "DX" IN THE TITLE OPEN YET
}

return TRUE;
}



int main(int argc, char *argv[])
{

hLib = LoadLibrary("cash.dll");
assert(hLib != NULL); // pass !!


while (1)
{
    EnumWindows(SearchProc, NULL);
}
return 0;
}

Any ideas why it would cause the crash?

If you need to see more code or get more information then please comment. I've deliberately only included the 'problem' piece of code for brevity and clarity.

axiac
  • 68,258
  • 9
  • 99
  • 134
John T
  • 1,078
  • 3
  • 14
  • 29
  • 1
    That may be where it crashes, but that doesn't mean it's the cause of the crash. We need to see more code. –  Jul 29 '17 at 14:34
  • 3
    As this is in a loop, where do you delete `lpszTitle`? Please create a [mcve] so we don't have to guess at the real code. What about error testing, you have a potential race condition as well. – Richard Critten Jul 29 '17 at 14:34
  • @RichardCritten I'm not deleting lpszTitle. I just thought it would be redefined on each pass of the loop? Do I need to delete it each time? I'll post more code now. Thanks – John T Jul 29 '17 at 14:43
  • And why would you use new in that case. As far as I understand, you know the title that you want to track so you can easily use a fixed buffer size that is somewhat longer that the actual title (so that if the actual caption is longer than the string you are tracking but otherwise identical, you would be able to know it is different) – Phil1970 Jul 29 '17 at 14:44
  • I hope you are not doing busy waiting in your loop. – Phil1970 Jul 29 '17 at 14:44
  • The formatting of the code could be improved. – pingul Jul 29 '17 at 14:50
  • @Phil1970 apologies but I'm very new to C++. I don't know the length of the title of the window but, I'm just looking for a window with "DX" in the title. I've posted more code now in my question. I'm also not sure what your second comment "I hope you are not doing busy waiting in your loop" means? Could you explain that a bit more. Thanks :) – John T Jul 29 '17 at 14:51
  • 1
    You have `new` with no accompanying `delete` --> memory leak. I would suggest a [book on C++](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – pingul Jul 29 '17 at 14:51
  • @pingul Thanks! This sorted it. I just added `delete[] lpszTitle;` in the 'else' part of that loop and it's fine now. If you put it as the answer I'll accept it. I will also take your advice about a C++ book! Thanks again :) – John T Jul 29 '17 at 15:06
  • 1
    and you need `GetWindowText(hWnd, lpszTitle, nLen+1);`, of course this not related to crash – RbMm Jul 29 '17 at 15:12
  • 1
    You should really be using [WinEvents](https://msdn.microsoft.com/en-us/library/windows/desktop/dd373889.aspx) to get notified whenever a window is created, instead of constantly polling. – IInspectable Jul 29 '17 at 15:16

1 Answers1

1

You allocate lpszTitle with new without ever deallocating it. Depending on how often the while-loop runs, you could run out of memory quite fast. Try to add a delete[] lpszTitle before the end of the function.

Some other tidbits:

  1. You seem to be mixing BOOL with bool. I would suggest going with bool, as it is standard C++.

  2. Manual memory allocation is old-school C++. Try out smart pointers.

  3. Why not use std::string (or std::wstring as suggested by @IInspectable in comments) instead of char[]?

  4. Declare variables when they are used, and not all in the start of the function (you might be coming from fortran?).

  5. Why is "using namespace std" considered bad practice?

However, I would suggest you post your final code to https://codereview.stackexchange.com for more and better input.

pingul
  • 3,351
  • 3
  • 25
  • 43
  • 1
    Incidentally, why not use `std::wstring`? The Windows API natively uses UTF-16, which `wchar_t` and `std::wstring` map to. ANSI encoding is a thing of the past. – IInspectable Jul 29 '17 at 15:23
  • @pingul Thanks for your great advice. It is really appreciated and I'll work on the code to improve it. Cheers :-) – John T Jul 29 '17 at 15:24
  • 1
    @IInspectable Thanks, I am not familiar to Windows. I added it to the answer and a reference to you. – pingul Jul 29 '17 at 16:26