C 将数组分配给具有复杂大小写的指针

C 将数组分配给具有复杂大小写的指针,c,arrays,pointers,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

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

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]);
}
如果在最后一行之后添加
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*/

inti;
int标志=0;
浮点arr1[3]={1.07,3.01,5.02};
浮动arr2[3]={2.07,6.01,9.02};
浮动arr3[3]={3.07,8.01,0.02};
浮动*ptr;
ptr=(浮动*)calloc(3,sizeof(浮动));
如果(标志==0){
ptr=arr1;
}
如果(标志==1){
ptr=arr2;
}
否则{
ptr=arr3;
}
对于(i=0;i
在这里,您将
ptr
设置为一个malloc'ed内存块,该内存块足够容纳3个浮点数。然后在下一行:

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

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

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

对于代码的最后一位,这是一个无效的初始值设定项:

float arr1[3]={{1.07,3.01,5.02}};
当我运行此代码时,
flag=0
显示第二个和第三个值为0,而
flag=1
flag=2
显示所有预期值

您只需要一组大括号:

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

当你把一个指针指向一个数组时,你的代码中绝对没有任何非法的东西。它甚至不会给你一个警告

指针是指针,它可以指向任何东西。有时您可能需要强制转换它,但指向相同基类型的数组不仅完全有效,甚至很常见


但是,您只能使用在堆上分配的空闲内存(malloc、calloc等)。数组是在堆栈上分配的,不需要释放,正如您已经看到的,如果这样做,您将得到运行时错误。

无错误解决方案

#include<stdio.h>  
#include<stdlib.h>

int main()
{
    float arr[]={1.2, 1.9, 3.1};
    float *ptr;
    int i;
    ptr = (float *)calloc(3,sizeof(float*));

    if(ptr == NULL){
     perror("calloc");
     return -ENOMEM;
    }
    //ptr = arr;

    // here you need to do something like this
    ptr[0] = arr[0];
    ptr[1] = arr[1];
    ptr[2] = arr[2];

    for (i=0;i<3;i++){
       printf("ptr[%d]=%f\n",i,ptr[i]);

           }
        free(ptr);
}
#包括
#包括
int main()
{
浮动arr[]={1.2,1.9,3.1};
浮动*ptr;
int i;
ptr=(浮动*)calloc(3,浮动*)的大小;
如果(ptr==NULL){
perror(“calloc”);
return-ENOMEM;
}
//ptr=arr;
//在这里,你需要这样做
ptr[0]=arr[0];
ptr[1]=arr[1];
ptr[2]=arr[2];
对于(i=0;i
分配数组

在C语言中,数组不能被赋值

您需要逐个元素分配元素

这里发生了什么

float arr[]={1.2, 1.9, 3.1};
float *ptr;

ptr = arr;
您将
ptr
分配给
arr[0]
的地址。这称为它的第一个元素的“(地址)”

没有数组元素被复制

为了证明这一点,你就去做吧

arr[0] = 42.;
然后运行打印循环

for (int i = 0; i < 3; ++i) 
{
  printf("ptr[%d] = %f\n", i, ptr[i]);
}

在一行中,您分配足够的字节以容纳三个浮点,并设置
ptr
的值以容纳该内存位置。在下一行中,更改
ptr
的值以容纳
arr
数组的地址,从而孤立您先前分配的内存。因为
ptr
指向的内存实际上是一个文本由三个浮点数组成的数组无法释放。应释放的内存已泄漏。OT:调用任何堆分配函数时:
malloc
calloc
realloc
1)返回的类型是
void*
,可以分配给任何指针。强制转换只会使代码变得混乱,使其更难理解、调试等。2)始终选中(!=NULL)确保操作成功的返回值与:
ptr=arr1;
和类似语句有关。这会通过调用
calloc()
覆盖指针中设置的值,从而导致内存泄漏。您的意思可能是:
memcpy(ptr,arr1,sizeof(arr1))
注意:在C语言中,引用数组的名称会降级为数组第一个字节的地址。@user3629249-我知道你的意思,但从技术上讲,数组“转换为一个类型为“指向类型的指针”的表达式,该表达式指向数组对象的初始元素”(degrades有点奇怪,但你会看到衰变——这本身不在标准中,但通常是可以理解的)请参见:。对于最后一段代码,如果我添加
free(ptr)
在最后一行,它仍然像前面一样有警告。@coco是的,出于同样的原因:您用本地数组的地址重写了malloc'ed内存。所以这个代码段仍然没有用,因为我们必须在使用它们之后取消分配内存。这是否意味着我必须找到另一种方法将数组分配给指针,如“for”loop?@coco您要么将本地数组复制到分配的内存中(要么使用
memcpy
或循环),要么完全取消分配。但是对于“交换指针”(如第一个示例),我们可以“释放”指针。是因为动态分配的内存仍然存在,而数组可以用常量指针覆盖它,使指针不再动态分配吗?@coco在第一个示例中,您根本没有分配任何内存,因此不,您无法释放它们。这不是错误,但不需要强制执行
mall的返回oc
(或
calloc
realloc
)是的,你不需要。看看你:你肯定有一个有趣的格式化支撑的方法……没错,你是对的,但是对于C++等其他语言之间的移植性,我喜欢这样做。这就是为什么有一个叫做C标准的东西和一个叫做C++标准的单独文档。(
if(ptr!=NULL)
)在使用内存之前。分配函数在失败时返回
NULL
(它们确实失败)。回想一下,在回答问题时,你进入了老师的名单。你正在帮助一个新学生学习编程。确保他记得你是
#include<stdio.h>  
#include<stdlib.h>

int main()
{
    float arr[]={1.2, 1.9, 3.1};
    float *ptr;
    int i;
    ptr = (float *)calloc(3,sizeof(float*));

    if(ptr == NULL){
     perror("calloc");
     return -ENOMEM;
    }
    //ptr = arr;

    // here you need to do something like this
    ptr[0] = arr[0];
    ptr[1] = arr[1];
    ptr[2] = arr[2];

    for (i=0;i<3;i++){
       printf("ptr[%d]=%f\n",i,ptr[i]);

           }
        free(ptr);
}
float arr[]={1.2, 1.9, 3.1};
float *ptr;

ptr = arr;
arr[0] = 42.;
for (int i = 0; i < 3; ++i) 
{
  printf("ptr[%d] = %f\n", i, ptr[i]);
}
ptr[0] = 42.000
ptr[1] = 1.9000
...