结构中指向数组的 cudaFree 指针上的 CUDA 分段错误

     2023-02-18     147

关键词:

【中文标题】结构中指向数组的 cudaFree 指针上的 CUDA 分段错误【英文标题】:CUDA Segmentation fault on cudaFree pointer to array in struct 【发布时间】:2021-05-22 20:44:05 【问题描述】:

我在 CUDA 设备上得到了一个结构,它包含一个指向数组的指针。计算、访问元素和一切正常,但是当我尝试成为一个好孩子并打电话时

cudaFree(my_struct->pointer_to_array)

我遇到了分段错误。 cudaFree(my_struct) 但是工作得很好。有什么我遗漏的吗?

请找到以下最小示例:

#include <stdio.h>

#include <cuda.h>
#include <cuda_runtime.h>
#include <cassert>

typedef struct 
  int n;
  float *arr;
 DummyStruct;

__global__ void check(DummyStruct *d) 
  printf("EL %f", d->arr[0]);


int main() 
  cudaError_t status;

  // create host pointer to dummy struct
  DummyStruct *dummy;
  dummy = (DummyStruct *)malloc(sizeof(DummyStruct));

  int arr_size = 32;

  dummy->n = 0;
  float *arr = (float *) malloc(sizeof(float) * arr_size);

  for (int i=0; i < 32; i++) 
    arr[i] = i;
  

  // allocate device array
  float *d_arr;
  status = cudaMalloc(&d_arr, arr_size * sizeof(float));
  assert( status == cudaSuccess );

  status = cudaMemcpy(d_arr, arr, arr_size * sizeof(float), cudaMemcpyHostToDevice);
  assert( status == cudaSuccess );

  free(arr);

  // for some reason this should happen here and not d_sp->coeff = d_coeff ...
  dummy->arr = d_arr;

  // allocate and ship struct to device
  DummyStruct* d_dummy;
  status = cudaMalloc(&d_dummy, sizeof(DummyStruct));
  assert( status == cudaSuccess );

  status = cudaMemcpy(d_dummy, dummy, sizeof(DummyStruct), cudaMemcpyHostToDevice);
  assert( status == cudaSuccess );

  // free host struct
  free(dummy);


  // check whether array access works
  check<<<1, 1>>>(d_dummy);


  // THIS causes Segmentation fault (core dumped)
  status = cudaFree(d_dummy->arr);
  assert( status == cudaSuccess );

  status = cudaFree(d_dummy);
  assert( status == cudaSuccess );

【问题讨论】:

【参考方案1】:

此声明:

status = cudaFree(d_dummy->arr);

需要在 host 代码中取消引用 device 指针(d_dummy - 使用设备分配器分配,即 cudaMalloc)。这在 CUDA 中是非法的。

既然您已经知道 (d_dummy-&gt;arr) == d_arr,那么释放嵌入指针的一种可能方法是:

status = cudaFree(d_arr);

类似的概念(取消引用主机代码中的设备指针)是此处注释的基础:

// for some reason this should happen here and not d_sp->coeff = d_coeff ...

【讨论】:

感谢您的及时回复。问题是,在我的真实代码中,我无法再访问 d_arr 我想做cudaFree (仅在上面的示例中)。是否可以引入辅助指针并在其上执行 cudaFree? 您可以将您的结构 (d_dummy) 复制回主机,然后从该主机副本中检索指针。或者在您执行dummy-&gt;arr = d_arr; 时,您可以添加另一行代码,例如float *d_helper_pointer = d_arr;,然后再执行cudaFree(d_helper_pointer);,我没有其他任何想法。我只能使用您显示的代码或您提供的描述。 确实,将结构复制回主机是有意义的。现在可以用了,谢谢!我想知道这种生活在设备上的结构是否被认为是好的风格...... 根据我的经验,使用结构作为内核参数是相当普遍的。带有嵌入式指针的结构可能有点挑战性,但您似乎已经正确导航了其中的大部分内容。如果您只打算将 1 个结构传递给内核,则通过值而不是指针传递可能更简单。如果您打算传递一个结构数组 (AoS),那么通常 SoA 方案比 AoS 更受欢迎,但我们在这里与您的问题相去甚远。 cuda SO 标签上有很多问题,讨论了这些不同的概念。

如何访问 C 中指向列表的指针结构数组?

】如何访问C中指向列表的指针结构数组?【英文标题】:HowdoyouaccessanarrayofstructsofpointerstolistsinC?【发布时间】:2020-07-1712:39:38【问题描述】:typedefstructAstructB*b;A;typedefstructBintx;structB*next;B;ATable[10];所以我有这两个结构,它应该是... 查看详情

C ++在指向结构的指针中访问类数组指针

】C++在指向结构的指针中访问类数组指针【英文标题】:C++accessingclassarraypointerinapointertoastructure【发布时间】:2019-12-0219:20:39【问题描述】:我是C++新手,我真的需要一些帮助。我正在尝试创建一个与GSLMonte-Carlo算法接口的结构... 查看详情

如何在C中释放指向结构的指针数组?

】如何在C中释放指向结构的指针数组?【英文标题】:HowtodeallocatearrayofpointerstostructuresinC?【发布时间】:2020-04-1515:45:54【问题描述】:我需要动态分配结构数组并对其执行一些操作,然后释放内存。当我尝试像那样释放内存时f... 查看详情

是否复制了新数组或指向结构中引用的数组的指针?

】是否复制了新数组或指向结构中引用的数组的指针?【英文标题】:Isanewarraycopiedorpointertoarrayreferencedinstruct?【发布时间】:2019-11-2318:41:41【问题描述】:#include<stdio.h>#include<stdlib.h>#include<string.h>#include<iostream>... 查看详情

分配指向结构数组的指针

】分配指向结构数组的指针【英文标题】:Mallocingpointertoarrayofstructs【发布时间】:2021-12-1403:51:07【问题描述】:我正在尝试使用一些自定义库来制作HTTP响应。库函数需要一个指向自定义结构HttpHeader的数组的指针。代码下方是... 查看详情

C:指向结构指针数组的指针(分配/解除分配问题)

】C:指向结构指针数组的指针(分配/解除分配问题)【英文标题】:C:pointertoarrayofpointerstostructures(allocation/deallocationissues)【发布时间】:2013-03-0202:53:41【问题描述】:我一直在回到C语言中,但我很难记住这种内存管理的大部分... 查看详情

在 C 中声明指向结构的指针数组,但在需要之前不为结构分配内存

】在C中声明指向结构的指针数组,但在需要之前不为结构分配内存【英文标题】:DeclaringanarrayofpointerstostructuresinC,butnotallocatingmemoryforstructureuntilneeded【发布时间】:2021-04-0409:54:13【问题描述】:我正在尝试为n指针数组分配空间... 查看详情

动态更改指向结构的指针数组的数据类型

】动态更改指向结构的指针数组的数据类型【英文标题】:Dynamicallychangethedatatypeofanarrayofpointerstoastruct【发布时间】:2018-11-1509:29:48【问题描述】:我正在尝试对结构中的变量指针数组进行编码。我的问题是结构内的变量具有不... 查看详情

程序的错误输出,使用指向结构数组的指针

】程序的错误输出,使用指向结构数组的指针【英文标题】:wrongoutputofprogramm,usingpointerstoanarrayofstructs【发布时间】:2021-09-2321:00:45【问题描述】:我正在尝试运行模拟并将点创建为结构。我现在想将它们存储在一个数组中并尝... 查看详情

在c++中初始化一个指向结构的指针数组(代码片段)

在C中初始化一个指向结构的指针数组可以使用复合文字来完成。typedefstructinta;intb;s;在C:s*ptrArray[]=&(s).a=1,.b=2,&(s).a=4,.b=5;如何在C++中完成?我也看到了在C++中使用复合语句初始化结构的区别:ss1=a:7,b:8;答案首先-在C语言中将... 查看详情

何时使指针指向堆上的结构与堆栈上的结构? [复制]

】何时使指针指向堆上的结构与堆栈上的结构?[复制]【英文标题】:Whentomakepointerpointtoastructontheheapvsonthestack?[duplicate]【发布时间】:2017-12-0913:54:00【问题描述】:#include<stdio.h>#include<stdlib.h>typedefstructfoochar*text;intnum;foo;... 查看详情

C:将指向结构的指针数组作为参数传递

】C:将指向结构的指针数组作为参数传递【英文标题】:C:Passinganarrayofpointerstostructsasanargument【发布时间】:2015-11-3014:38:00【问题描述】:这个问题很可能已经回答了,所以我将非常简单地解释一下:我已经定义了一个“列表”... 查看详情

C:指向结构数组的指针的动态数组

】C:指向结构数组的指针的动态数组【英文标题】:C:Dynamicarrayofpointerstoarrayofstructure【发布时间】:2011-01-0217:24:53【问题描述】:我有一个结构和这些结构的二维数组:typedefstructcharexit_n;charexit_s;charexit_w;charexit_e;room;roommap[MAP_WID... 查看详情

使用指向结构数组的指针不会返回完整的数组

】使用指向结构数组的指针不会返回完整的数组【英文标题】:Usingapointertoanarrayofstructsdoesnotreturnthecompletearray【发布时间】:2021-11-3010:45:11【问题描述】:我有一个主程序,它应该通过调用函数来加载数据(结构数组,未定义大... 查看详情

如何初始化指向结构的指针数组?

】如何初始化指向结构的指针数组?【英文标题】:HowcanIinitializeanarrayofpointerstostructs?【发布时间】:2010-09-1617:27:11【问题描述】:是否可以初始化指向结构的指针数组?比如:structcountry_t*countries[]="UnitedStatesofAmerica","America","Engl... 查看详情

指向结构的指针上的点运算符

】指向结构的指针上的点运算符【英文标题】:Dotoperatoronpointertoastruct【发布时间】:2019-09-1914:54:57【问题描述】:假设我有一个结构typedefstructlist_entryintval;intval2;list_entry;和一个指向它的指针list_entrylist;list_entry*pList=&list;那么... 查看详情

第二次作业

...址。指针可以指向整形、浮点型、字符型、函数、数组、结构体等一些数据类型。指针指向数组或字符串时指向的是数组首地址。指向二维数组时,指针指向的是二维数组中的第一个元素,也是一个数组。数组名与指针可以通用... 查看详情

定义指向结构数组的指针

】定义指向结构数组的指针【英文标题】:Definingpointerstoarrayofstructs【发布时间】:2018-10-2004:38:38【问题描述】:我遇到了这段代码:typedefstructchar*name;char*value;SPAM;typedefstructchar*name;intnum_spams;SPAM*spams;EGG;SPAMmy_spams[2]="name1","value1","... 查看详情