我正在关注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();
但这即使函数使用完全相同的代码并返回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.org中,VkExtensionProperties
如下所示:
typedef struct VkExtensionProperties {
char extensionName[VK_MAX_EXTENSION_NAME_SIZE];
uint32_t specVersion;
} VkExtensionProperties;
...在这一行上:
extensionNames.push_back(extensionProperties[i].extensionName);
...您要存储到
extensionNames
中的是指向存在于extensionProperties
中的数组的指针,该数组在函数中是局部的。从函数返回时,所有数组都与extensionProperties
一起被破坏,并且所有指针现在都悬空了。当Vulkan尝试使用这些死指针时,您得到的是未定义的行为。