问题描述
这是我的代码:
const char* sdl_extensions;
const char** sdl_extensions_list;
if (!SDL_Vulkan_GetInstanceExtensions(p_window,&sdl_extension_count,&sdl_extensions))
{
printf("sdl_extension_count = %i\n",sdl_extension_count);
printf("[ERROR]: SDL_Vulkan_GetInstanceExtensions _2\n");
exit(0);
}
else
{
for(int i = 0; i < sdl_extension_count; i++)
{
printf("sdl_extension_%i = %s\n",i,*(&sdl_extensions + i));
}
sdl_extensions_list = &sdl_extensions;
for(int i = 0; i < sdl_extension_count; i++)
{
printf("sdl_extension_%i = %s\n",*(&sdl_extensions + i));
}
}
这里是输出:
sdl_extension_count = 2
sdl_extension_0 = VK_KHR_surface
sdl_extension_1 = VK_KHR_xlib_surface
sdl_extension_0 = VK_KHR_surface
sdl_extension_1 = diz?�
为什么在“sdl_extensions_list = &sdl_extensions;”行之后我有错误的输出(sdl_extension_1 = diz?�)?
谢谢!
解决方法
从读取 the SDL_Vulkan_GetInstanceExtensions
documentation 开始,您需要传递一个指向 SDL_Vulkan_GetInstanceExtensions
的指针数组,然后函数初始化这些指针。
上面文档中的例子也说明你需要调用SDL_Vulkan_GetInstanceExtensions
两次:首先获取元素数;然后在创建数组后再次获取实际列表。
在 C 中执行此操作的代码如下所示:
unsigned int count;
SDL_Vulkan_GetInstanceExtensions(window,&count,NULL);
const char **extensions = malloc(sizeof(const char *) * count);
SDL_Vulkan_GetInstanceExtensions(window,extensions);
for (size_t i = 0; i < count; ++i)
{
printf("Extension %zu: %s\n",i,extensions[i]);
}
[重要提示:错误处理留给读者作为练习]
记住free
完成后你malloc
的记忆。
为了解释代码中的 &sdl_extensions
和我的示例中的 extensions
之间的区别,让我们画出它们并看看它们的区别。
第一个sdl_extensions
和指针&sdl_extensions
:
+-----------------+ +----------------+ | &sdl_extensions | ---> | sdl_extensions | +-----------------+ +----------------+
然后是我示例中的 extensions
(假设 count
为 2
):
+------------+ +---------------+---------------+ | extensions | ---> | extensions[0] | extensions[1] | +------------+ +---------------+---------------+
从这两张图片很容易看出这里的一个主要问题:&sdl_extensions
指向一个 single const char *
“元素”,而 extensions
指向一个两个元素的数组。
因为 SDL_Vulkan_GetInstanceExtensions
将参数视为指向包含 count
指针的数组的第一个元素的指针,您的代码将导致 SDL_Vulkan_GetInstanceExtensions
写出您的单元素的边界“数组”,这会导致未定义行为。