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

CUDA结构体内存分配报错:数组字段bits分配时出现段错误

问题原因

z_cu是通过cudaMalloc分配的设备内存指针,主机代码无法直接访问设备内存中的结构体成员。在z_cu_from_z函数里,to指向设备内存,直接执行&to->bits相当于尝试读取设备内存中结构体的bits字段地址,主机端没有权限直接操作设备地址空间,因此触发段错误。

修复方案

有两种常见的修复思路,任选其一即可:

方案1:主机端构建完整结构体后拷贝到设备

先在主机内存中创建z_cu_t实例,完成bits的设备内存分配,再将整个结构体拷贝到设备:

修改main.cu:

#include "z_cu_t.cuh"

int main()
{
    z_t z = z_init(2);
    z_cu_t z_cu_host; // 主机端结构体实例
    z_cu_t* z_cu_dev;

    z_cu_from_z(&z_cu_host, &z); // 先在主机端构建结构体
    cudaMalloc(&z_cu_dev, sizeof(z_cu_t));
    cudaMemcpy(z_cu_dev, &z_cu_host, sizeof(z_cu_t), cudaMemcpyHostToDevice);

    z_free(&z);
    z_cu_free<<<1, 1>>>(z_cu_dev);
    cudaFree(z_cu_dev);
    cudaFree(z_cu_host.bits); // 释放主机结构体持有的设备指针
    
    return 0;
}

修改z_cu_t.cu中的z_cu_from_z函数:

void z_cu_from_z(z_cu_t* to, z_t const* from)
{
    to->size = from->size;
    cudaMalloc(&to->bits, sizeof(int) * from->size);
    cudaMemcpy(to->bits, from->bits, sizeof(int) * from->size, cudaMemcpyHostToDevice);
}

方案2:通过cudaMemcpy修改设备结构体成员

保持z_cu为设备指针,先分配bits的设备内存,再将指针值拷贝到设备结构体的bits字段:

修改z_cu_t.cu中的z_cu_from_z函数:

void z_cu_from_z(z_cu_t* to, z_t const* from)
{
    // 拷贝size字段到设备
    cudaMemcpy(&to->size, &from->size, sizeof(size_t), cudaMemcpyHostToDevice);
    
    // 分配bits的设备内存,得到设备指针
    int* d_bits;
    cudaMalloc(&d_bits, sizeof(int) * from->size);
    // 将d_bits指针拷贝到设备结构体的bits字段
    cudaMemcpy(&to->bits, &d_bits, sizeof(int*), cudaMemcpyHostToDevice);
    
    cudaMemcpy(d_bits, from->bits, sizeof(int) * from->size, cudaMemcpyHostToDevice);
}
额外注意事项
  • 主机指针和设备指针属于不同的地址空间,主机不能直接解引用设备指针访问其成员。
  • 释放内存时要确保所有分配的设备内存都被释放,避免内存泄漏。

内容的提问来源于stack exchange,提问作者P'tit Ju

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 11:29:51