在C中初始化整数指针数组

问题描述 投票:0回答:4

我对 C 中指针的使用有一些困惑/问题。我在下面放了示例代码以方便理解。请注意这些代码的差异。如果您在理解时遇到问题,请反馈。

这行不通。

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

void process() {
    int *arr;
    arr=(int*)malloc(5*sizeof(int));
    arr=(int*){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

但这有效。

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

void process() {
    int *arr;
    arr=(int*)malloc(5*sizeof(int));
    arr=(int[]){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

这也有效。为什么?我这里没有分配内存。

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

void process() {
    int *arr;
    arr=(int[]){3,1,4,5,2};
    for(int z=0;z<5;z++) {
        printf("%d ",arr[z]);
    }
    printf("\n");
}

int main() {
    process();
    return 0;
}

为什么它们不一样?

    arr=(int*){3,1,4,5,2};
    arr=(int[]){3,1,4,5,2};

有没有其他方法来初始化整数指针数组,而不是在这种单独的分配方式中使用?

arr[0]=3;
arr[1]=1;
arr[2]=4;
arr[3]=5;
arr[4]=2;

我怎样才能获得指针内存中分配的大小/数量,以便我可以静态使用

for(int z=0;z<NUM;z++) {
而不是
for(int z=0;z<5;z++) {
之类的东西?

任何答案都将受到高度赞赏。

提前致谢。

c arrays pointers
4个回答
19
投票

前几个示例中的

malloc
调用分配一块内存,并将指向该内存的指针分配给
arr
。一旦您再次分配给
arr
,指针值就会被覆盖,并且您将失去对分配的内存的跟踪 - 即,您已经泄漏了它。这就是一个错误。

换句话说,如果您使用

malloc()
分配一块内存,那么您可以使用数组语法向其中写入数据(例如):

int* arr = (int *) malloc(sizeof(int) * 5);
for (int i=0; i<5; ++i)
    arr[i] = i;

但是您不能直接向

arr
分配任何其他内容,否则您将丢失指向该内存块的指针。当您使用
malloc()
分配块时,不要忘记在不再需要它时使用
free()
将其删除。

数组不是指向整数的指针;它是一个数组。当您将数组名称作为参数传递给接受指针作为参数的函数时,数组名称被称为“衰减为指针”,但它们不是同一件事。

关于你的最后一个问题:这实际上是数组和类型指针之间的区别:编译器知道数组的大小,但它不知道任意类型指针指向的块的大小。不幸的是,答案是否定的。

但是由于您正在编写 C++,而不是 C,因此无论如何您都不应该使用数组:使用 `std::vector'!他们知道自己的长度,而且可以扩展。


7
投票

当你说:

ptr = {1,2,3,4,5}
时,你让
ptr
指向数据段中的内存,常量数组
{1,2,3,4,5}
驻留在其中,因此你正在泄漏内存。如果你想初始化你的内存,在分配后,写:
ptr[0]=1; ptr[1]=2;
等等。如果要复制数据,请使用memcpy


2
投票

以逗号分隔的值列表是用于初始化数组的构造。它不适合初始化数组指针。这就是为什么你需要那个

(int[])
- 它告诉 gcc 创建一个未命名的整数数组,并使用提供的值进行初始化。

gcc 不会让你丢失

arr
是一个数组的信息,除非你真的愿意。这就是为什么你需要演员阵容。最好将
arr
声明为数组,而不是指针。您仍然可以将其传递给接受指针的函数。然而 gcc 不会让你用 malloc 泄漏内存:

error: incompatible types when assigning to type ‘int[5]’ from type ‘void *’

如果您想要一个可以是数组或指向已分配内存的指针的变量,请为其创建另一个变量。更好的是,创建一个接受指针的函数并向其传递数组或指针。


0
投票

我觉得我可以进一步澄清已接受的答案。

当你用例如初始化数组时

int arr1[]={1,2,3,4,5};

这会在 stack 上保留内存,用值

{1,2,3,4,5}
填充它,并将
arr
设置为指向该内存块的指针。

当您使用

new
初始化数组时:

arr2 = new float[5];

这会在上保留内存并返回指向该内存块的指针。如果您随后致电:

arr2 = arr1;

您将丢失为 arr2 预留的 heap 内存的地址。这就是内存泄漏。

正确的方法是使用

arr1
:
memcpy

值从堆栈复制到堆中
memcpy(arr2, arr1, sizeof(arr1)); // src, dest, #bytes
© www.soinside.com 2019 - 2024. All rights reserved.