之前没怎么用指针,就很少去搞清楚指针取址这些的内涵。导致现在用起来很费劲,就去补一补之前的知识
1.指针、引用、取址的区别
1.1定义时的*和&
指针*
类型名 *var
int *point; // 表示point是指针,指向int型变量
&作引用的关键字
类型名 & 别名 = var;
int &b=var; //表示b是引用,为var的别名,对b的所有操作等同于对var的操作·
指针和引用的区别
指针可以为空,引用不能为空
1.2使用时的*和&
- *在使用时表示取内容。
- &在使用时表示取地址。
程序示例
#include<iostream>
using namespace std;
int main(){
int a=1;
int &c=a; //c是a的别名
int *b=&a; //b为指针,指向a的地址
cout<<c<<endl; //c是a的别名,输出c也就是输出a
cout<<&c<<endl; //c的地址=a的地址
cout<<&a<<endl; //同上一行
cout<<*&c<<endl; //先取址,再取内容
cout<<b<<endl; //b为指向a的指针,这里输出a的地址
cout<<*b<<endl; //该指针指向地址的内容
}
2.cudaMalloc()
int *dev_a; //dev_a是一个指针,指向int型变量,存储在主存上,他的内容就是所指变量的地址
size_t size=1024*sizeof(int);
cudaMalloc((void**) &dev_a,size);
为什么是&dev_a而不是dev_a?
- dev_a是一个指针,存储在主存上;size为一个1024个int的一维数组大小
- cudaMalloc在显存上申请一个size大小的数组
- 取dev_a的地址是为了将cudaMalloc在显存上获得的数组首地址赋值给dev_a。
- 相当于普通的函数调用,是进行值传递还是引用传递。这里相当于调用一个cudaMalloc函数,如果传入dev_a的话,相当于值传递,函数分配好内存后,将地址赋值给dev_a,不会传递到函数外;如果传入&dev_a,相当于引用传递,&能真正改变该地址存储的变量值。
cudaMalloc在执行完成后,向这个地址(&dev_a)中写入了一个地址值(此地址值是GPU显存里的),也就是上边所说,将cudaMalloc在显存上获得的数组首地址赋值给dev_a。
为什么要(void **)?
&dev_a其实就相当于指针的地址,dev_a是一个指针,用一个指针存dev_a的地址,如果用一个变量来表示&dev_a的话,应该是 void ** temp= &dev_a
在定义时就是**
。也就是说 &dev_a
本身的含义就是指针的指针。
根据函数原型,需要是指针的指针(**),所以用void**进行强制类型转化,使得形参实参匹配。
如何理解CUDA中的cudaMalloc()的参数:https://blog.csdn.net/bendanban/article/details/8151335
总结
调用cudaMalloc的作用是分配一个给定大小的空间,返回给传入的地址参数,使得dev_a指向新分配的空间的地址。如果调用cudaMalloc时传入变量名(dev_a)的话,只能进行值传递,而无法进行引用传递,所以要传入变量地址(&dev_a)。由于dev_a是一个指针,指针的地址(&dev_a) 如果用一个变量(temp)来存储的话,也就是该变量是存储(&dev_a)的指针,指向&dev_a,是指针的指针,即void ** temp = &dev_a;
2.cudaMemcpy()
cudaError_t cudaMemcpy (void *dst, const void *src, size_t count, cudaMemcpyKind kind)。
前两个参数都是指针数据类型,含义是地址,因为指针存的就是地址。
double x[N];
double *dev_x;
cudaMalloc( (void**)&dev_x, sizeof(double)*num_v);
cudaMemcpy(dev_x,x,num_v*sizeof(double),cudaMemcpyHostToDevice);
这里前两个参数都要求是指针的形式,其中x由于定义的是double型数组,所以x其实就是数组的起始地址,可以理解为指向数组的指针。
3.cudaFree()
cudaFree(dev_a);
根据函数原型,第一个参数是指针类型,而dev_a就是指针,所以直接传参而不用进行类型转化。
为什么这里是void* 而cudaMalloc是void**?
因为释放内存的时候,其实不像cudaMalloc,需要函数修改参数(新分配内存的地址),而是只将所指向的内存地址的空间释放就好。
如何理解CUDA中的cudaMalloc()的参数 https://blog.csdn.net/bendanban/article/details/8151335
C++中指针和引用的区别、以及引用和取地址符&的区别 https://blog.csdn.net/jinking01/article/details/82796024