C 将指向指针数组的指针理解为函数中的参数
当我试图自学C语言时,我遇到了一个我想开发的简单程序。它只是试图利用指针到指针数组来制作类似于矩阵的东西。我在Windows上编译,当我运行它时,它崩溃了,同时,在Linux上尝试这段代码,它说是分段错误,这是因为函数参数是数组吗?我做错了什么C 将指向指针数组的指针理解为函数中的参数,c,arrays,pointers,C,Arrays,Pointers,当我试图自学C语言时,我遇到了一个我想开发的简单程序。它只是试图利用指针到指针数组来制作类似于矩阵的东西。我在Windows上编译,当我运行它时,它崩溃了,同时,在Linux上尝试这段代码,它说是分段错误,这是因为函数参数是数组吗?我做错了什么 #include <stdio.h> #include <stdlib.h> void initializeArray(float** array, int size); void printArray(float** arra
#include <stdio.h>
#include <stdlib.h>
void initializeArray(float** array, int size);
void printArray(float** array, int size);
int main()
{
float** array_1 = NULL;
int array_size = 3;
initializeArray(array_1, array_size);
// Free memory from array
for (int i = 0; i < array_size; i++)
{
free(array_1[i]);
}
free(array_1);
return 0;
}
void initializeArray(float** array, int size)
{
array = malloc(size * sizeof(float*));
if (array)
{
for (int i = 0; i < size; i++)
{
array[i] = malloc(size * sizeof(float));
if (!array[i])
{
exit(0);
}
}
}
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
array[i][j] = 0;
}
}
}
void printArray(float** array, int size)
{
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
printf("%f\t", array[i][j]);
}
printf("\n");
}
}
执行以下操作时:
void initializeArray(float** array, int size)
{
array = malloc(size * sizeof(float*));
您没有在函数外更改数组,因此数组_1在调用后和调用前一样指向NULL,并创建内存泄漏。您需要返回它,或者将其作为三个***指针传递,并将其用作*数组,但这不太方便
float **initializeArray(int size)
{
float** array = malloc(size * sizeof(float*));
...
return array;
}
从main:
array_1 = initializeArray(array_size);
如果希望函数修改参数值,则必须传递指向该参数的指针:
void foo( T *ptr )
{
*ptr = new_value(); // write a new value to the thing ptr points to
}
void bar( void )
{
T var;
foo( &var ); // write a new value to var
}
这适用于任何类型T,包括指针类型。用P*替换T,我们得到
void foo( P **ptr )
{
*ptr = new_value(); // write a new value to the thing ptr points to
}
void bar( void )
{
P *var;
foo( &var ); // write a new *pointer* value to var
}
基本上,无论var的类型是什么,您都需要为ptr增加一个间接级别
将其应用于代码:
void initializeArray(float*** array, int size)
{
*array = malloc(size * sizeof(float*));
if (*array)
{
for (int i = 0; i < size; i++)
{
(*array)[i] = malloc(size * sizeof(float)); // parens matter; you want
if (!(*array)[i]) // to index into what array *points
{ // to*, not array itself
exit(0);
}
}
}
for (int i = 0; i < size; i++)
{
for (int j = 0; j < size; j++)
{
(*array)[i][j] = 0;
}
}
}
有几点建议:
首先,在调用malloc时,将sizeof运算符的操作数作为解除引用的目标,而不是类型名:
ptr = malloc( N * sizeof *ptr );
在你的情况下,应该是
*array = malloc( size * sizeof **array ); // sizeof operand has one more level of
// indirection than target
及
如果您更改阵列的类型,这将保护您;您不必追踪sizeof float或sizeof float*的每个实例并更改它们
其次,您分配的不是2D数组,而是指针数组,每个指针指向一个单独的浮点数组。这很好,取决于您正在做什么,只需注意这些行在内存中不是相邻的-数组[1][2]后面的对象不会是数组[2][0]
如果要分配一个连续的多维数组,可以使用
float (*array)[3] = malloc( 3 * sizeof *array );
为连续的3x3数组留出空间。使用VLA语法,您可以编写如下函数
void initializeArray( size_t rows, size_t cols, float (**array)[cols] )
{
*array = malloc( rows * sizeof **array );
if ( *array )
{
for ( size_t i = 0; i < rows; i++ )
for ( size_t j = 0; j < rows; j++ )
(*array)[i][j] = initial_value();
}
}
作为一名三星级程序员并不是一种恭维是的,三星级程序员:你倾向于避免这种情况。@Jean-Françoisfare啊,我明白了,没有注意到这一点,但在那之后,我应该如何调用main中的函数?将其分配给数组_1是否足够?
float (*array)[3] = malloc( 3 * sizeof *array );
void initializeArray( size_t rows, size_t cols, float (**array)[cols] )
{
*array = malloc( rows * sizeof **array );
if ( *array )
{
for ( size_t i = 0; i < rows; i++ )
for ( size_t j = 0; j < rows; j++ )
(*array)[i][j] = initial_value();
}
}