0

コンパイラ:http ://sourceforge.net/projects/mingwbuilds/files/

#include <iostream>
#include <string.h>
#include <windows.h>
using namespace std;

  const wchar_t* readConsole(int chars_to_read) {
    wchar_t* wcharFromConsole = new wchar_t[chars_to_read+1];
    COORD pos = {0,0};
    DWORD dwChars;
    if (!ReadConsoleOutputCharacterW(
      GetStdHandle(STD_OUTPUT_HANDLE),
      wcharFromConsole,  // Buffer where store symbols
      chars_to_read,     // number of chars to read
      pos,    // Read from row=8, column=6
      &dwChars // How many symbols stored
    ))
    {
      printf("ReadConsoleOutputCharacterW failed %d\n", GetLastError());
      abort();
    }
    wcharFromConsole [dwChars] = L'\0'; // Terminate, so string functions can be used
    wstring ws = wcharFromConsole;
    return ws.c_str();
  }

int main() {
  for (int i = 1; i<=0x3000; i++) {
    printf("wcslen: %X \n",wcslen(readConsole(i)));
  }
  system("pause");
}

このループはで終了し0x1FF1、pauseは呼び出されません。wstringを削除すると、この問題が解消されるようです。しかし、空白のトリミングなどの機能のためにここで必要です。ここではあまり関係ありませんが、wstringを呼び出すととにかくその問題が発生するのはなぜですか?プログラムが単に終了するというエラーメッセージはありません。

更新されたコード、ループはで終了します0x2BBF

#include <iostream>
#include <string.h>
#include <windows.h>
using namespace std;

  const wchar_t* readConsole(int chars_to_read) {
    wchar_t* wcharFromConsole = new wchar_t[chars_to_read+1];
    COORD pos = {0,0};
    DWORD dwChars;
    if (!ReadConsoleOutputCharacterW(
      GetStdHandle(STD_OUTPUT_HANDLE),
      wcharFromConsole,  // Buffer where store symbols
      chars_to_read,     // number of chars to read
      pos,    // Read from row=8, column=6
      &dwChars // How many symbols stored
    ))
    {
      printf("ReadConsoleOutputCharacterW failed %d\n", GetLastError());
      abort();
    }
    wcharFromConsole [dwChars] = L'\0'; // Terminate, so string functions can be used
    wstring ws = wcharFromConsole;
    delete [] wcharFromConsole;
    const wchar_t* wc = ws.c_str();
    return wc;
  }

int main() {
  for (int i = 1; i<=0x3000; i++) {
    printf("wcslen: %X \n",wcslen(readConsole(i)));
  }
  system("pause");
}
4

1 に答える 1

2

痛い。

wstring ws = wcharFromConsole;
return ws.c_str();

基本的に、ここではデッドポインタを返します。文字列は戻り時に破棄されるため、呼び出し元に到達するポインタは無効になります。

編集:「新しい」が削除されることはないため、メモリリークも発生しています。しかし、それは一般的に目に見える問題を引き起こさず、プログラムのメモリ使用量を増やすだけです。

于 2012-07-22T22:49:27.190 に答える