C语言 分配内存时sizeof *ptr与sizeof**ptr之间的差异

ca1c2owp  于 2022-12-03  发布在  其他
关注(0)|答案(3)|浏览(197)

在这段代码中:

void func(size_t dim, double **ptr){
   (*ptr) = malloc(dim * sizeof **ptr);
   /* Perform Calculations...*/
}

使用sizeof **ptrsizeof *ptr有什么区别?这让我很困惑。当我处理int*double*类型时,似乎没有区别,但当我处理chars*时,使用sizeof **ptr会导致分段错误。您能帮助我解决这个问题吗?
提前感谢!

8hhllhi2

8hhllhi21#

使用sizeof **ptrsizeof *ptr有什么区别?
sizeof *ptrptr指向的类型的大小。
sizeof **ptrptr所指向之型别的大小。
声明double **ptr表示ptr是指向double的指针,那么*ptr是指向double的指针,所以sizeof *ptr是指向double的指针的大小,**ptrdouble,所以sizeof **ptrdouble的大小。
当我处理int*double*类型时,这似乎没有区别,但当我处理chars*时,使用sizeof **ptr会导致分段错误。
如果在系统中指针是四个字节,int是四个字节,double是八个字节,那么为intdouble分配足够的空间也会为指针分配足够的空间。但是,为char分配的空间对指针来说是不够的。
这实际上不太可能对单个指针产生明显的不同,因为malloc通常以8或16字节为单位工作,所以要求它为char分配空间实际上会为一个指针给予足够的空间,尽管编译器进行了优化。如果分配dim * sizeof **ptr字节,其中ptr具有char **类型,并且dim较大,则这将仅为dimchar元素分配足够的空间,而没有为dim指针分配足够的空间。

bf1o4zei

bf1o4zei2#

参数ptr声明如下

double **ptr

也就是说,用作参数的原始指针通过指向它的指针间接地通过引用传递给函数。
在函数中,您需要通过取消引用参数的方式为原始指针赋值。

(*ptr) = malloc(dim * sizeof **ptr);

原始指针*ptr必须被赋以动态分配的双精度数组的地址。

sizeof **ptr

您将获得double类型的对象的大小。
为了使它更清楚,您可以使用例如中间指针,如

double *tmp = malloc(dim * sizeof *tmp );
*ptr = tmp;

至于表达式sizeof *ptr中的操作数的类型,则它具有double *类型,并且它产生指针类型double *的对象的大小,而不是类型double的对象的所需大小。

lc8prwob

lc8prwob3#

sizeof()操作符中的指针不会被求值,假设您有这样的情况:

int * pointer = malloc(sizeof(* pointer));

你在这里做的是“malloc sizeof pointed type”,优点是你可以改变指针的类型而不改变sizeof()部分。
现在,使用双指针:

int ** pointer;

// allocate enough space to store a pointer: sizeof(* pointer) <--> sizeof(int *) 
pointer = malloc(sizeof(* pointer));

还有这个:

int ** pointer;
// allocate enough space to store an int: sizeof(** pointer) <--> sizeof(int) 
pointer = malloc(sizeof(** pointer));

在64位系统上,第一种情况可能会给予您8个字节,而第二种情况只有4个字节,如果您打算使用8个字节,则可能会崩溃。

(*ptr) = malloc(dim * sizeof **ptr);

因为ptr的类型为double**,所以您在内部存储的是double* 类型的 ptr。您分配的是nsizeof(double)字节,而不是nsizeof(double)字节,这在您的系统上可能有所不同。
或者当你访问那个内存的时候崩溃了。

相关问题