为什么从方法中获取 vulkan 扩展会导致 vulkan 实例创建失败?

why does getting vulkan extensions from a method fail vulkan instance creation?

我正在学习 vulkan-tutorial.com 教程,我正在执行验证层步骤。在教程 Alexander Overvoorde 中,作者将用于实例创建的可用扩展的收集移到了它自己的函数中。

std::vector<const char*> getRequiredExtensions()

之前我收集的信息有点不同,因为我使用的是 SDL2 而不是 glfw,但是我的程序 运行 具有实例创建且没有验证错误。问题是当我将代码移至此函数时,我无法再创建实例。

这很好用:

unsigned int extensionCount = 0;
vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, NULL);
std::vector<VkExtensionProperties> extensionProperties(extensionCount);
vkEnumerateInstanceExtensionProperties(NULL, &extensionCount, extensionProperties.data());
std::vector<const char*> extensionNames;
std::cout << "available extensions:" << std::endl;
int i = 0;
while (i < extensionCount) {
    extensionNames.push_back(extensionProperties[i].extensionName);
    std::cout << extensionNames[i] << std::endl;
    i++;
}
if (enableValidationLayers) {
    extensionNames.push_back(VK_EXT_DEBUG_REPORT_EXTENSION_NAME);
}*/
createInfo.enabledExtensionCount = extensionCount;
createInfo.ppEnabledExtensionNames = extensionNames.data();

但是即使该函数使用完全相同的代码和 returns extensionNames,这还是失败了,然后我像这样使用它:

std::vector<const char*> extensionNames = getRequiredExtensions();
createInfo.enabledExtensionCount = static_cast<uint32_t>(extensionNames.size());
createInfo.ppEnabledExtensionNames = extensionNames.data();

那为什么这行不通呢?我有 java 的正式教学背景,但用 C++ 编写代码已有一年,所以它可能是我发送错误的语法错误或指针。另外

reateInfo.enabledExtensionCount = static_cast<uint32_t>(getRequiredExtensions().size());

工作得很好,所以返回的向量大小正确:我相信是 5,因为我有 4 个扩展加上调试一个。

来自 the documentation at Khronos.orgVkExtensionProperties 看起来像这样:

typedef struct VkExtensionProperties {
    char        extensionName[VK_MAX_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
} VkExtensionProperties;

...所以在这一行:

extensionNames.push_back(extensionProperties[i].extensionName);

...您存储到 extensionNames 中的是指向位于 extensionProperties 中的数组的指针,它是您函数的本地数组。当您从函数中 return 时,所有数组都与 extensionProperties 一起被破坏,并且您所有的指针现在都悬空了。
当 Vulkan 尝试使用这些死指针时,您得到的是未定义的行为。