将 const char* 分配给 const char** 后,出现错误

问题描述

这是我的代码

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(假设 count2):

+------------+      +---------------+---------------+
| extensions | ---> | extensions[0] | extensions[1] |
+------------+      +---------------+---------------+

从这两张图片很容易看出这里的一个主要问题:&sdl_extensions 指向一个 single const char * “元素”,而 extensions 指向一个两个元素的数组。

因为 SDL_Vulkan_GetInstanceExtensions 将参数视为指向包含 count 指针的数组的第一个元素的指针,您的代码将导致 SDL_Vulkan_GetInstanceExtensions 写出您的单元素的边界“数组”,这会导致未定义行为