You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

初始化Vulkan Instance时触发读取访问违例问题排查

问题:调用vkCreateInstance触发vulkan-1.dll读取访问违例

调用vkCreateInstance()初始化Vulkan Instance时,触发来自vulkan-1.dll的读取访问违例错误。开发环境为Visual Studio 2022,使用SDL管理窗口,Windows系统与显卡驱动均已更新至最新版本,相关代码如下:

#include <vulkan/vulkan.hpp>

#include <SDL.h>
#include <SDL_vulkan.h>
#include <vector>
#include <iostream>

SDL_Window* window;
int main(int argc, char *argv[]) {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cout << "Video initialization failed:" << std::endl;
    }
    window = SDL_CreateWindow("vkTest", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN);
    SDL_vulkanInstance inst;
    VkInstanceCreateInfo inst_info;
    VkApplicationInfo appInfo;
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = "engine";
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.pEngineName = "engine";
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.apiVersion = VK_API_VERSION_1_0;

    inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    inst_info.pApplicationInfo = &appInfo;

    inst_info.flags = 0;

    uint32_t vkExtensionCount = 0;
    
    if (!SDL_Vulkan_GetInstanceExtensions(window, &vkExtensionCount, NULL)) {
        std::cout << "Unable to get Vulkan extensions." << std::endl;
        exit(EXIT_FAILURE);
    }

    std::vector<const char*> vkExtensions;
    vkExtensions.resize(vkExtensionCount);

    if (!SDL_Vulkan_GetInstanceExtensions(window, &vkExtensionCount, vkExtensions.data())) {
        std::cout << "Unable to get Vulkan extensions." << std::endl;
        exit(EXIT_FAILURE);
    }
    std::cout << *vkExtensions.data() << std::endl;

    inst_info.enabledExtensionCount = vkExtensionCount;
    inst_info.ppEnabledExtensionNames = vkExtensions.data();

    inst_info.enabledLayerCount = 0;

    VkResult res = vkCreateInstance(&inst_info, nullptr, &inst);
    if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
        std::cout << "Cannot find compadible vulkan driver." << std::endl;
        exit(EXIT_FAILURE);
    }
    else if (res) {
        std::cout << "unknown error" << std::endl;
        exit(EXIT_FAILURE);
    }
}

错误原因分析

  1. 变量类型错误:SDL_vulkanInstance不是标准Vulkan的VkInstance类型,vkCreateInstance需要传入VkInstance*类型指针,类型不匹配会导致写入非法内存区域,直接触发访问违例。
  2. 结构体未完全初始化:VkInstanceCreateInfo的pNext、ppEnabledLayerNames等未使用的指针成员未初始化为nullptr,Vulkan要求所有结构体的未使用指针成员必须显式设为nullptr,否则会引发未定义行为。
  3. 未定义窗口尺寸宏:SCREEN_WIDTH和SCREEN_HEIGHT未定义,可能导致SDL窗口创建失败,后续传入无效窗口句柄给SDL_Vulkan_GetInstanceExtensions引发连锁错误。
  4. 错误处理不完整:SDL_Init失败后未直接退出,SDL_CreateWindow返回nullptr时未做错误处理,可能导致后续操作使用无效窗口句柄。

修复步骤

  • 将SDL_vulkanInstance inst;改为VkInstance inst = nullptr;,使用标准Vulkan实例类型。
  • 显式初始化VkInstanceCreateInfo的所有未使用成员为nullptr,或用值初始化({})自动清零。
  • 定义SCREEN_WIDTH和SCREEN_HEIGHT的具体值,例如#define SCREEN_WIDTH 800和#define SCREEN_HEIGHT 600。
  • 完善错误处理:SDL_Init失败后直接退出,检查SDL_CreateWindow返回值,确保窗口创建成功。

修正后的代码

#include <vulkan/vulkan.hpp>

#include <SDL.h>
#include <SDL_vulkan.h>
#include <vector>
#include <iostream>

#define SCREEN_WIDTH 800
#define SCREEN_HEIGHT 600

SDL_Window* window;
int main(int argc, char *argv[]) {
    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        std::cout << "Video initialization failed: " << SDL_GetError() << std::endl;
        exit(EXIT_FAILURE);
    }

    window = SDL_CreateWindow("vkTest", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN | SDL_WINDOW_VULKAN);
    if (!window) {
        std::cout << "Window creation failed: " << SDL_GetError() << std::endl;
        exit(EXIT_FAILURE);
    }

    VkInstance inst = nullptr;
    VkInstanceCreateInfo inst_info{}; // 值初始化自动将所有成员设为0/nullptr
    VkApplicationInfo appInfo{};
    
    appInfo.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    appInfo.pApplicationName = "engine";
    appInfo.applicationVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.pEngineName = "engine";
    appInfo.engineVersion = VK_MAKE_VERSION(1, 0, 0);
    appInfo.apiVersion = VK_API_VERSION_1_0;

    inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    inst_info.pApplicationInfo = &appInfo;
    inst_info.flags = 0;

    uint32_t vkExtensionCount = 0;
    if (!SDL_Vulkan_GetInstanceExtensions(window, &vkExtensionCount, NULL)) {
        std::cout << "Unable to get Vulkan extensions: " << SDL_GetError() << std::endl;
        exit(EXIT_FAILURE);
    }

    std::vector<const char*> vkExtensions(vkExtensionCount);
    if (!SDL_Vulkan_GetInstanceExtensions(window, &vkExtensionCount, vkExtensions.data())) {
        std::cout << "Unable to get Vulkan extensions: " << SDL_GetError() << std::endl;
        exit(EXIT_FAILURE);
    }

    inst_info.enabledExtensionCount = vkExtensionCount;
    inst_info.ppEnabledExtensionNames = vkExtensions.data();
    inst_info.enabledLayerCount = 0;
    inst_info.ppEnabledLayerNames = nullptr; // 显式设为nullptr

    VkResult res = vkCreateInstance(&inst_info, nullptr, &inst);
    if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
        std::cout << "Cannot find compatible vulkan driver." << std::endl;
        exit(EXIT_FAILURE);
    } else if (res != VK_SUCCESS) {
        std::cout << "Unknown error, result code: " << res << std::endl;
        exit(EXIT_FAILURE);
    }

    // 销毁Vulkan实例
    if (inst != nullptr) {
        vkDestroyInstance(inst, nullptr);
    }

    SDL_DestroyWindow(window);
    SDL_Quit();
    return 0;
}

内容的提问来源于stack exchange,提问作者bub1401

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 06:05:29