c - 将数组分配给具有复杂情况的指针

标签 c arrays pointers

如果我们将一个指针分配给另一个指针,这称为“交换指针”。例如,

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]);
}

这段代码片段通过了编译并正确运行(非法代码得到正确答案?):

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 = (float *)calloc(3,sizeof(float));

在这里,您将 ptr 设置为一个足够大的 malloc 内存块,可容纳 3 个 float 。然后在下一行:

ptr = arr;

您用 arr 覆盖了 ptr 的值,导致内存泄漏。这是合法的,因为在这样的赋值中,数组衰减为指向其第一个元素的指针。

然后当您打印 ptr 指向的值时,您会在 arr 中获得值,因为那是 ptr 指向的位置。

这也是为什么在 ptr 上调用 free 无效的原因,因为它不再指向分配的内存。

至于最后一段代码,这是一个无效的初始化器:

float arr1[3]={{1.07,3.01,5.02}};

当我运行这段代码时,flag=0 显示第二个和第三个值是 0,而 flag=1flag=2显示了所有预期值。

你只需要一套牙套:

float arr1[3]={1.07,3.01,5.02};

关于c - 将数组分配给具有复杂情况的指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51296178/

相关文章:

C - 动态创建字符串数组(malloc)

c - 将 char** 传递给函数,不会改变它的值,还是会改变?

javascript - 通过过滤器数组设置对象数组的属性

c - C语言读取文本文件

c++ - 当我尝试使用指针的别名时 g++ 返回错误

c - fgets() 读取的字符少于预期

javascript - 将表达式拆分为具有多个键的数组,并在数组中包含键

javascript - Angular 2 - 绑定(bind)数字数组以选择选项

c++ - 将原始数据类型转换为 void 指针类型

c++ - 同步 ISR 访问是否需要 volatile?