以下是完整代码,运行时会在238行出现访问冲突和堆栈溢出的错误,但238行是一个累加赋值语句。查看已申请的堆内存,大约0.5GB。应该不至于溢出啊?
编译环境:vs2017
测试输入:[任意一运行的程序的窗口的标题] 1017
正常退出时会显示pause命令的输出(按任意按键继续)不正常退出会闪退
改为使用安全函数后,223行出现新错误,图片在1群里
liveRPG.h
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <malloc.h>
#include <process.h>
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#pragma comment (lib, "ws2_32.lib")
//#include "cJSON.h"
#define PAUSE do{system("pause");}while(0)
typedef struct GameStruct
{
HWND hwnd;
HDC hdc;
} Game;
main.c
// #define _CRT_SECURE_NO_WARNINGS
#define WIN32_LEAN_AND_MEAN
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include "liveRPG.h"
char gameWndTitle[100];
char liveRoomNum[10];
Game *rpg;
Game *choiseWnd;
HINSTANCE hInstance;
_Bool GetGameWndInfor(Game *G, char* WndName);
LRESULT CALLBACK ChoiseWndProc(HWND, UINT, WPARAM, LPARAM);
void CreateChoiseWnd(void* null);
_Bool GetBiliLiveRoomCommit(char* lrn, char* r);
int main(void)
{
HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE);
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD mode;
GetConsoleMode(hStdin, &mode);
mode &= ~ENABLE_QUICK_EDIT_MODE; //移除快速编辑模式
mode &= ~ENABLE_INSERT_MODE; //移除插入模式
SetConsoleMode(hStdin, mode);
char strTitle[255];
GetConsoleTitleA(strTitle, 255);
HWND hw = FindWindowA("ConsoleWindowClass", strTitle);
CONSOLE_CURSOR_INFO CursorInfo;
GetConsoleCursorInfo(hStdout, &CursorInfo);
CursorInfo.bVisible = FALSE;
SetConsoleCursorInfo(hStdout, &CursorInfo);
CONSOLE_FONT_INFO consoleCurrentFont;
GetCurrentConsoleFont(hStdout, FALSE, &consoleCurrentFont);
int iconY = consoleCurrentFont.dwFontSize.Y;
hInstance = GetModuleHandle(NULL);
SetConsoleTitleA("liveRPG!");
rpg = (Game*)malloc(sizeof(Game)); //游戏本身
choiseWnd = (Game*)malloc(sizeof(Game)); //为了显示附加信息而创建的全透明窗口
printf("\n"
".__ .__ ____________________ ________ \n"
"| | |__|__ __ ____\\______ \\______ \\/ _____/ \n"
"| | | \\ \\/ // __ \\| _/| ___/ \\ ___ \n"
"| |_| |\\ /\\ ___/| | \\| | \\ \\_\\ \\\n"
"|____/__| \\_/ \\___ >____|_ /|____| \\______ /\n"
" \\/ \\/ \\/ \n"
"---------------------------------------------------\n"
"Welcome! There is liveRPG, you can use me to live RPG game and viewer can choise the game's option.\n"
"please type the game's Window title\n"
">");
scanf_s("%[^\n]", &gameWndTitle, 100);
//HDC i1 = GetDC(LoadImage(hInstance, MAKEINTRESOURCE( IDI_ICON1 ), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR));
//HDC i2 = GetDC(LoadImage(hInstance, MAKEINTRESOURCE( IDI_ICON2 ), IMAGE_ICON, 32, 32, LR_DEFAULTCOLOR));
//BitBlt(GetDC(GetConsoleWindow()), 0, iconY * 12, iconY * 2, iconY * 2, i1, 0, 0, SRCCOPY);
printf("\n\nplease type your live room number\n>");
scanf_s("%s", &liveRoomNum, 10);
if (!GetGameWndInfor(rpg, gameWndTitle))
{
free(rpg);
free(choiseWnd);
return (-1);
}
_beginthread(CreateChoiseWnd, 0, NULL);
Sleep(100);
char* res = NULL;
//while (TRUE)
{
//BitBlt(choiseWnd->hdc, 0, 0, 1024, 768, rpg->hdc, 0, 0, SRCCOPY);
GetBiliLiveRoomCommit(liveRoomNum, res);
printf("%s", res);
free(res);
Sleep(10);
}
PAUSE;
free(rpg);
free(choiseWnd);
return 0;
}
_Bool GetGameWndInfor(Game *G, char* WndName)
{
//WCHAR wWndName[100];
//mbtowc(wWndName, WndName, strlen(WndName));
G->hwnd = FindWindowA(NULL, WndName);
if (!G->hwnd)
{
return FALSE;
}
G->hdc = GetDC(G->hwnd);
if (!G->hdc)
{
return FALSE;
}
return TRUE;
}
void CreateChoiseWnd(void* null)
{
WNDCLASS wc = { 0 };
wc.hbrBackground = CreateSolidBrush(RGB(0, 255, 0));
wc.lpfnWndProc = ChoiseWndProc;
wc.lpszClassName = L"liveRPG choise wnd";
wc.hInstance = GetModuleHandle(NULL);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
RegisterClass(&wc);
choiseWnd->hwnd = CreateWindowExW(0l/*WS_EX_LAYERED*/,
L"liveRPG choise wnd", L"",
WS_POPUP | WS_VISIBLE,
CW_USEDEFAULT, 0,
1024, 768,
NULL, NULL, GetModuleHandle(NULL), NULL);
//SetLayeredWindowAttributes(W->hwnd, RGB(0, 0, 0), 1, LWA_COLORKEY | LWA_ALPHA);
ShowWindow(choiseWnd->hwnd, SW_SHOW);
UpdateWindow(choiseWnd->hwnd);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return;
}
LRESULT CALLBACK ChoiseWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_PAINT:
{
PAINTSTRUCT ps;
choiseWnd->hdc = BeginPaint(hWnd, &ps);
// TODO: 在此处添加使用 hdc 的任何绘图代码...
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
_Bool GetBiliLiveRoomCommit(char* lrn, char* r)
{
WORD sockVersion = MAKEWORD(2, 2);
WSADATA wsaData;
if (WSAStartup(sockVersion, &wsaData) != 0)
{
fprintf(stderr, "error - WSAStartup!");
return FALSE;
}
SOCKET slisten = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (slisten == INVALID_SOCKET)
{
fprintf(stderr, "error - invalid socket!");
return FALSE;
}
/*
ADDRINFO addr;
ADDRINFO hint;
hint.ai_family = AF_INET; /* hint 的限定设置
hint.ai_socktype = SOCK_STREAM; /* 这里可是设置 socket type 比如 SOCK——DGRAM
hint.ai_flags = AI_ALL; /* flags 的标志很多 。常用的有AI_CANONNAME;
hint.ai_protocol = 0; /* 设置协议 一般为0,默认
hint.ai_addrlen = 0; /* 下面不可以设置,为0,或者为NULL
hint.ai_canonname = NULL;
hint.ai_addr = NULL;
hint.ai_next = NULL;
if (!GetAddrInfoW(L"api.live.bilibili.com", L"http", &hint, &addr))
{
fprintf(stderr, "error - get host IP error!");
return FALSE;
}*/
HOSTENT *remoteHost;
if ((remoteHost = gethostbyname("api.live.bilibili.com")) == NULL) //通过主机名获取地址
{
fprintf(stderr, "error - can not find IP!");
return FALSE;
}
int a = WSAGetLastError();
//char addrTMP[5];
//strcpy(addrTMP, remoteHost->h_addr_list[0]);
SOCKADDR_IN serAddr;
serAddr.sin_family = AF_INET;
serAddr.sin_port = htons(80);
serAddr.sin_addr.s_addr = inet_addr(inet_ntoa(*(struct in_addr*)remoteHost->h_addr_list[0]));
if (connect(slisten, ((const SOCKADDR *)(&serAddr)), sizeof(serAddr)))
{
fprintf(stderr, "error - connect error!");
return FALSE;
}
char *buffer = (char*)malloc(321 + strlen(lrn));
strcpy_s(buffer, 45, "GET /xlive/web-room/v1/dM/gethistory?roomid=");
strcat_s(buffer, strlen(lrn) + 1, lrn);
strcat_s(buffer, 286, " HTTP/1.1\r\nHost: api.live.bilibili.com\r\nAccept: */*\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.87 Safari/537.36\r\nConnection: keep-alive\r\nCache-Control: no-cache\r\nContent-Type: application/x-www-form-urlencoded\r\n\r\n\r\nroomid=");
strcat_s(buffer, strlen(lrn) + 1, lrn);
send(slisten, buffer, (int)strlen(buffer), 0);
unsigned long long l = 1;
int test = 0;
char Tmp[1];
//char *testC = (char*)malloc(1024);
//memset(testC, 0, 1024);
_Bool isHeader = TRUE;
_Bool isN = FALSE;
while (isHeader)
{
l = recv(slisten, Tmp, 1, 0);
test = WSAGetLastError();
switch (*Tmp)
{
case '\r':
break;
case '\n'://判断HTTP头是否接受完毕
if (isN == TRUE)
isHeader = FALSE;
isN = TRUE;
break;
default:
isN = FALSE;
break;
}
//strcat(testC, Tmp);
}
//free(testC);
char *jsonTmp = (char*)malloc(1025);
unsigned long long sum = 0;
while (l > 0)
{
l = recv(slisten, Tmp, 1024, 0);
strcat_s(jsonTmp, l + 1, Tmp);
sum = sum + l;
jsonTmp = (char*)realloc(jsonTmp, sum + 1026);
if (l < 1024)
break;
}
free(jsonTmp);
char *JSON = (char*)malloc(sum);
strcpy_s(JSON, sum, jsonTmp);
JSON[sum + 1] = '\0';
r = JSON;
closesocket(slisten);
WSACleanup();
free(buffer);
return TRUE;
}