【发布时间】:2018-07-12 01:32:26
【问题描述】:
如果我们将一个指针分配给另一个指针,则称为“交换指针”。例如,
float *temp, *ptr1, *ptr2;
temp = ptr1;
ptr1 = ptr2;
ptr2 = temp;
但是,如果我们将数组分配给指针,这是非法的,因为数组并不是真正的指针类型。但是看看接下来的 3 个例子:
float arr[]={1.2, 1.9, 3.1};
float *ptr;
int i;
ptr = (float *)calloc(3,sizeof(float));
ptr = arr;
for (i=0;i<3;i++){
printf("ptr[%d]=%f\n",i,ptr[i]);
}
这段代码sn-p通过编译并正确运行(非法代码得到正确答案?):
ptr[0]=1.200000
ptr[1]=1.900000
ptr[2]=3.100000
如果我在最后一行之后添加free(ptr),即
float arr[]={1.2, 1.9, 3.1};
float *ptr;
int i;
ptr = (float *)calloc(3,sizeof(float));
ptr = arr;
for (i=0;i<3;i++){
printf("ptr[%d]=%f\n",i,ptr[i]);
}
free(ptr); /*add free here*/
这次出现了警告:
warning: attempt to free a non-heap object ‘arr’ [-Wfree-nonheap-object]
int i;
int flag=0;
float arr1[3]={1.07,3.01,5.02};
float arr2[3]={2.07,6.01,9.02};
float arr3[3]={3.07,8.01,0.02};
float *ptr;
ptr = (float *)calloc(3,sizeof(float));
if(flag==0){
ptr = arr1;
}
else if(flag==1){
ptr = arr2;
}
else{
ptr = arr3;
}
for (i=0;i<3;i++){
printf("ptr[%d]=%f\n",i,ptr[i]);
}
使用不同的flag 可以正常运行,但是如果我在最后一行添加free(ptr),它仍然会像之前一样出现警告。
有人帮忙分析一下原因吗?
【问题讨论】:
-
在一行上分配足够的字节来保存三个浮点数,并设置
ptr的值来保存该内存位置。在下一行更改ptr的值以保存arr数组的地址,从而孤立您之前分配的内存。由于ptr指向的内存实际上是三个浮点数的文字数组,因此您无法释放它。你应该释放的内存已经泄露。 -
OT:当调用任何堆分配函数时:
malloccallocrealloc1) 返回的类型是void*,可以分配给任何指针。强制转换只会使代码混乱,使其更难以理解、调试等。2) 始终检查 (!=NULL) 返回值以确保操作成功 -
关于:
ptr = arr1;和类似声明。这会通过调用calloc()覆盖在指针中设置的值,从而导致内存泄漏。也许您的意思是:memcpy( ptr, arr1, sizeof( arr1) );注意:在 C 中,引用数组的名称会降级为数组第一个字节的地址。 -
@user3629249 - 我知道你的意思,但从技术上讲,数组是“转换为类型为''pointer to type''的表达式,它指向数组对象的初始元素” (degrades 有点奇怪,但你会看到 decays ——它本身不在标准中,但通常理解)见:@ 987654321@.