创建一个进程并等待它完成后,它的STARTUPINFO是否仍然可用还是被破坏了?
STARTUPINFO si;
bRes = CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
dwRes = WaitForSingleObject(pi.hProcess, INFINITE);
在此之后,si
被修改/销毁还是保持不变?
答案 0 :(得分:2)
Windows为新进程创建启动信息结构的副本。这必须发生,因为新流程有一个全新的地址空间,无法看到你的结构。
现在,您的结构会发生什么?好吧,documentation有答案。该参数注释如下:
_In_ LPSTARTUPINFO lpStartupInfo
_In_
表示通过调用CreateProcess
不会修改结构的内容。因此,您可以确信当CreateProcess
返回时,启动信息结构尚未被修改。
答案 1 :(得分:0)
Windows创建的STARTUPINFO的副本已销毁。但是您提供给CreateProcess函数的结构仍然存在。
答案 2 :(得分:0)
如果你宣布它就像你做的那样
STARTUPINFO si;
然后当它被声明的程序的一部分完成时它被C销毁(它被称为“超出范围”)。例如:
void myfunct() {
STARTUPINFO si1;
if (condition) {
STARTUPINFO si2;
//...
} //si2 destroyed here
//...
} //si1 destroyed here
即使CreateProcess()
函数想要保留si1或si2,它也不能。因为无论你做什么,它们都会在那些点被摧毁。
现在,如果您创建了这样的:
STARTUPINFO *si = malloc(sizeof(STARTUPINFO));
然后只有在你明确调用
时它才会被销毁free(si);
某些API函数要求您为其提供可保留的内容。对于这些功能,您必须以第二种或更复杂的方式分配参数,并且它们会在文档中告诉您何时必须在以后销毁它。
但是大多数API函数只是复制传递给它们的任何内容并保留源代码,因此可以将指针传递给以第一种方式声明的结构。
请注意,一般情况下,“将某些内容传递给API并依赖API销毁它”是不可取的。您调用的应用程序和API函数最有可能使用不同的内存管理器。在一个中分配的内容不能在另一个中释放。
因此,大多数情况下,此类API会要求您通过调用某些特定函数来分配数据,或者(更常见)只是稍后自己删除数据。
MYPARAM *p = malloc(sizeof(MYPARAM));
APIOpen(p);
//...much later
APIClose(p);
//It's now safe to free p
free(p);