创建一个进程并等待它完成后,它的 STARTUPINFO 是否仍然可用或已被破坏?
STARTUPINFO si;
bRes = CreateProcess(NULL, command, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
dwRes = WaitForSingleObject(pi.hProcess, INFINITE);
在此之后是否si
被修改/销毁或保持不变?
Windows 为新进程创建启动信息结构的副本。这必须发生,因为新进程具有全新的地址空间并且看不到您的结构。
现在,你的结构会发生什么?好吧,文档有答案。参数注释如下:
_In_ LPSTARTUPINFO lpStartupInfo
这_In_
意味着结构的内容不会被调用修改CreateProcess
。因此,您可以确信在CreateProcess
返回时,启动信息结构没有被修改。
Windows 创建的 STARTUPINFO的副本被销毁。但是您提供给 CreateProcess 函数的结构仍然存在。
如果你像以前那样声明它
STARTUPINFO si;
然后,当声明它的程序部分完成时,它被 C 销毁(称为“超出范围”)。例如:
void myfunct() {
STARTUPINFO si1;
if (condition) {
STARTUPINFO si2;
//...
} //si2 destroyed here
//...
} //si1 destroyed here
即使CreateProcess()
函数想要保留 si1 或 si2,它也不能。因为无论你做什么,它们都会在那个时候被摧毁。
现在,如果您像这样创建 si:
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);