(int*)在c中动态分配int数组时
因此,我对如何在C中创建一个返回int数组指针的函数感到有点困惑。我知道您不能这样做:(int*)在c中动态分配int数组时,c,arrays,pointers,memory-management,C,Arrays,Pointers,Memory Management,因此,我对如何在C中创建一个返回int数组指针的函数感到有点困惑。我知道您不能这样做: int* myFunction() { int myInt[aDefinedSize]; return myInt; } 因为这是返回一个指向局部变量的指针。 所以,我想到了这个: int* myFunction(){ int* myInt = (int) malloc(aDefinedSize * sizeof(int)); return myInt; } 这将产生错误:警告从指针强制转
int* myFunction() {
int myInt[aDefinedSize];
return myInt; }
因为这是返回一个指向局部变量的指针。
所以,我想到了这个:
int* myFunction(){
int* myInt = (int) malloc(aDefinedSize * sizeof(int));
return myInt; }
这将产生错误:警告从指针强制转换为不同大小的整数
这意味着要使用它,它可以:
int* myFunction(){
int* myInt = (int*) malloc(aDefinedSize * sizeof(int));
return myInt; }
但让我困惑的是:
malloc之前的(int*)向我解释了这一点:它告诉编译器所分配内存的数据类型是什么。例如,当您在数组中单步执行并且编译器需要知道要递增多少字节时,将使用此选项。
所以,如果我得到的解释是正确的,那么内存不是被分配给足够数量的指向int的指针,而不是实际上的int吗?因此,myInt不是指向int的指针数组的指针吗?
理解这一点的一些帮助将是非常好的。谢谢
malloc
分配字节数组并返回指向第一个字节的void*
。或NULL
如果分配失败
若要将此数组视为不同数据类型的数组,必须将指针强制转换为该数据类型
在C中,void*
隐式转换为任何数据指针类型,因此不需要显式转换:
int* allocateIntArray(unsigned number_of_elements) {
int* int_array = malloc(number_of_elements * sizeof(int)); // <--- no cast is required here.
return int_array;
}
int*分配数组(元素的无符号数){
int*int_数组=malloc(元素数*sizeof(int));//
所以,如果我得到的解释是正确的,那么内存不是被分配给足够数量的指向int的指针,而不是实际上的int吗
不,您要求malloc
查找aDefinedSize*sizeof(int)
字节,而不是
aDefinedSize*sizeof(int*)
bytes。这是您获得的内存大小,类型取决于用于访问内存的指针
因此,myInt不是指向int的指针数组的指针吗
不,因为您将它定义为int*
,所以它是指向一个int的指针
当然,指针不知道分配的内存有多大,但只指向适合它的第一个int
。这取决于程序员跟踪大小
请注意。malloc
返回一个void*
,可以将其静默分配给任何指针,如下所示:
int* myInt = malloc(aDefinedSize * sizeof(int));
指针上的算术运算以指向类型的步幅进行,即使用int*p
,p[3]
与*(p+3)
相同,这大致意味着“转到p
,以字节为单位前进三次sizeof(int)
,并访问该位置”。
int**q
将是指向一个int的指针,可能指向一个指针数组。C中的数组
在C语言中,你要记住数组只是内存中的一个地址,加上一个长度和一个对象类型。当你把它作为一个参数传递给一个函数或一个函数的返回值时,这个长度会被忘记,并且它会与第一个元素的地址互换处理。这导致了在使用它的程序中出现很多安全漏洞读或写超过缓冲区的末尾
在大多数上下文中,数组的名称会自动转换为其第一个元素的地址,因此,例如,您可以将数组或指针传递给memmove()
,但也有一些例外情况,即它也有一个长度
数组上的运算符是数组中的字节数,但是sizeof()
指针是指针变量的大小。因此,如果我们声明inta[size];
,sizeof(a)
与sizeof(int)*(size\t)(size)
相同,而sizeof(&a[0])
与sizeof(int*)相同
。另一个重要的问题是,编译器通常可以在编译时判断数组访问是否超出范围,而不知道对指针的哪些访问是安全的
如何返回数组
如果要返回指向相同静态数组的指针,并且每次调用函数时都会得到相同的数组,则可以执行以下操作:
#define ARRAY_SIZE 32U
int* get_static_array(void)
{
static int the_array[ARRAY_SIZE];
return the_array;
}
不能在静态数组上调用free()
如果要创建动态数组,可以执行以下操作,尽管这是一个人为的示例:
#include <stdlib.h>
int* make_dynamic_array(size_t n)
// Returns an array that you must free with free().
{
return calloc( n, sizeof(int) );
}
除非由于某种原因数组指针会更改,例如:
int* p = calloc( n, sizeof(int) );
/* ... */
p = realloc( p, new_size );
一般来说,我建议calloc()
而不是malloc()
,因为它会将内存块初始化为零,而malloc()
会保留未指定的内容。这意味着,如果您有读取未初始化内存的错误,请使用calloc()
将始终为您提供可预测、可重复的结果,并且每次使用malloc()
都会给您带来不同的未定义行为。特别是,如果您分配一个指针,然后在0
是指针的陷阱值的实现上取消引用它(如典型的桌面CPU),由calloc()
创建的指针总是会立即给您一个segfault,而由malloc()创建的垃圾指针
看起来似乎可以工作,但会损坏内存的任何部分。这种错误很难追踪。在调试器中,比起任意值是有效值还是垃圾值,更容易看到内存是否被清零
进一步讨论
在注释中,有一个人反对我使用的一些术语。特别是,C++提供了几种不同的方法来返回对数组的引用,这些数组保存了关于其类型的更多信息,例如:
#include <array>
#include <cstdlib>
using std::size_t;
constexpr size_t size = 16U;
using int_array = int[size];
int_array& get_static_array()
{
static int the_array[size];
return the_array;
}
std::array<int, size>& get_static_std_array()
{
static std::array<int, size> the_array;
return the_array;
}
#包括
#包括
使用std::size\u t;
constexpr size\u t size=16U;
使用int_数组=int[size];
int_数组和get_static_数组()
{
静态int_数组[size];
返回_数组;
}
std::array&get_static_std_array()
{
静态std::array\u数组;
返回_数组;
}
因此,一位评论者(如果我理解正确的话)反对“返回
#include <array>
#include <cstdlib>
using std::size_t;
constexpr size_t size = 16U;
using int_array = int[size];
int_array& get_static_array()
{
static int the_array[size];
return the_array;
}
std::array<int, size>& get_static_std_array()
{
static std::array<int, size> the_array;
return the_array;
}