#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
const int iParams = 3;
const int iWorkTimeDef = 5000;
const int iMemSizeDef = 10;
const int iMemSizeMax = 1024;
int iMemSize = iMemSizeDef;
int iWorkTime = iWorkTimeDef;
bool bChild = false;
char *cParams[] = {"-ms","-mb","-take"};
int *iBuf = NULL;
bool InterpretParams(int argc, char *argv[])
{
int j;
if (argc == 1) return true;
for (int i = 1; i < argc; i = i+2)
{
j = 0;
while ((strcmp(argv,cParams[j])!=0) && (j<iParams))j++;
switch (j)
{
case 0: //-ms
if ((i+1 >= argc) || !(iWorkTime = atoi(argv[i+1])))
{
printf("Wrong argument in %s key\n",cParams[j]);
iWorkTime = iWorkTimeDef;
}
break;
case 1: //-mb
if ((i+1 >= argc) || !(iMemSize = atoi(argv[i+1])))
{
printf("Wrong argument in %s key\n",cParams[j]);
iMemSize = iMemSizeDef;
}
break;
case 2: //-take
bChild = true;
if ((i+2 >= argc) || !(iMemSize = atoi(argv[i+1])) || !(iWorkTime = atoi(argv[i+2])))
{
printf("Wrong arguments in %s key\n",cParams[j]);
return false;
}
printf("Requesting %d MB memory.\n",iMemSize);
iBuf = (int *) malloc(iMemSize*1024*1024);
printf("Going to sleep\n");
Sleep(iWorkTime);
printf("Going to free memory\n");
free(iBuf);
break;
default:
printf("Unknown parameter: %s\n",argv);
return false;
}
}
return true;
}
int main(int argc, char* argv[], char* env[])
{
char cCom[1024] = "\"";
char cComBuf[1024] = "";
int i = 0;
HANDLE* pHandle;
STARTUPINFOA sInf;
PROCESS_INFORMATION* pInf;
int iChild;
strcat(cCom,argv[0]);
strcat(cCom,"\" -take ");
if (!InterpretParams(argc,argv))
{
printf("Halt.\n");
getch();
return 1;
}
if (bChild)
{
printf("Child process fin.\n");
return 1;
}
iChild = iMemSize/iMemSizeMax + 1;
ZeroMemory(&sInf,sizeof(STARTUPINFO));
sInf.cb = sizeof(sInf);
pInf = (PROCESS_INFORMATION*) malloc(iChild*sizeof(PROCESS_INFORMATION));
if (pInf == NULL)
{
printf("Can't allocate memory for process information\n");
return 1;
}
ZeroMemory(pInf,iChild*sizeof(pInf));
pHandle = (HANDLE*) malloc(iChild*sizeof(HANDLE));
if (pHandle == NULL)
{
printf("Can't allocate memory for handles\n");
free(pInf);
return 1;
}
printf("Creating %d processes for %d ms\n",iChild,iWorkTime);
while (iMemSize / iMemSizeMax >= 1)
{
strcpy(cComBuf,cCom);
sprintf(&cComBuf[strlen(cComBuf)],"%d %d",iMemSizeMax,iWorkTime);
iMemSize = iMemSize - iMemSizeMax;
if (!CreateProcessA( NULL, cComBuf,
NULL, NULL,
false,0,
NULL, NULL,
&sInf,&pInf))
{
iChild = i+1;
printf("Can't create process #%d\n",i);
iMemSize = -1;
};
pHandle = pInf.hProcess;
i++;
}
if (iMemSize > 0)
{
strcpy(cComBuf,cCom);
sprintf(&cComBuf[strlen(cComBuf)],"%d %d",iMemSize,iWorkTime);
CreateProcessA( NULL, cComBuf,
NULL, NULL,
true,0,
NULL, NULL,
&sInf,&pInf);
pHandle = pInf.hProcess;
}
printf("Waiting.\n");
WaitForMultipleObjects(iChild,pHandle,true,INFINITE);
printf("Closing handles\n");
for (i=0; i<iChild; i++)
{
CloseHandle(pInf.hProcess);
CloseHandle(pInf.hThread);
}
return 1;
}
CreateProcess, WaitForMultipleObjects и ошибка
Имеется консольная программа.
Суть программы:
CreateProcess вызывает ещё один или несколько экземпляров программы, но с другим параметром, которые в свою очередь только и делают, что просто занимают память и ждут некоторое время.
Ошибка вылетает на этапе, когда "дочерние" процессы заканчивают работу. Причем, судя по тому, что количество окон с предложением "отправить отчет об ошибке" соответствует количеству "дочерних" процессов, ошибка закралась где-то в них. А отладчик VS2008 скромно молчит, т.к. "родительский" процесс завершает работу без ошибок.
Код:
Код:
Пока еще не разбирался в коде, но сразу вопрос - пробовали запускать в отладчике процесс с этими "другими" параметрами?
Во-первых, при запуске дочернего процесса вы передаете параметр как ' -take' (с пробелом в начале), а проверяете на '-take' (без пробела), так что условие
Код:
(strcmp(argv,cParams[j])!=0)
никогда не будет true.
Во-вторых, если хотите задать именно такое условие
Код:
((strcmp(argv,cParams[j])!=0) && (j<iParams))
то его надо делать так
Код:
( (j<iParams) && (strcmp(argv,cParams[j])!=0) )
Дальше этого места код не смотрел.
Цитата: nikitozz
Во-первых, при запуске дочернего процесса вы передаете параметр как ' -take' (с пробелом в начале), а проверяете на '-take' (без пробела), так что условие
Код:
(strcmp(argv,cParams[j])!=0)
никогда не будет true.
Строка формируется вида: "<путь>" -take <val1> <val2>
И пробел тут к месту, иначе -take мы не найдем в массиве argv[] - а там он лежит как раз в виде "-take" (без пробела).
Цитата: nikitozz
Во-вторых, если хотите задать именно такое условие
Код:
((strcmp(argv,cParams[j])!=0) && (j<iParams))
то его надо делать так
Код:
( (j<iParams) && (strcmp(argv,cParams[j])!=0) )
Да, действительно :) проглядел - угроза обращения за пределы массива.
Ошибка была решена, добавлением одной строки: i++
в case 2 после free(iBuf)
Цитата: nikitozz
Во-вторых, если хотите задать именно такое условие
,то его надо делать так
Код:
((strcmp(argv,cParams[j])!=0) && (j<iParams))
Код:
( (j<iParams) && (strcmp(argv,cParams[j])!=0) )
Каково различие в этих кодах?Ведь по сути это одно и тоже,только с разным порядком?Или дело в том,что,проверив 1е условие во 2м случае и найдя его равным False,проверка дальше не пойдёт?
Цитата: @pixo $oft
Извините,что не совсем в тему,но хотелось бы узнать вот чтоКаково различие в этих кодах?Ведь по сути это одно и тоже,только с разным порядком?Или [COLOR="Red"]дело в том,что,проверив 1е условие во 2м случае и найдя его равным False,проверка дальше не пойдёт[/COLOR]?
Именно так.
Цитата: @pixo $oft
Извините,что не совсем в тему,но хотелось бы узнать вот чтоКаково различие в этих кодах?Ведь по сути это одно и тоже,только с разным порядком?Или дело в том,что,проверив 1е условие во 2м случае и найдя его равным False,проверка дальше не пойдёт?
В том то и вся суть :)
Ведь cParams массив из 3 элементов. Так что если мы сначала не проверим, что j < 3, то получим cParams[3].