Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 将指向指针数组的指针理解为函数中的参数_C_Arrays_Pointers - Fatal编程技术网

C 将指向指针数组的指针理解为函数中的参数

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

当我试图自学C语言时,我遇到了一个我想开发的简单程序。它只是试图利用指针到指针数组来制作类似于矩阵的东西。我在Windows上编译,当我运行它时,它崩溃了,同时,在Linux上尝试这段代码,它说是分段错误,这是因为函数参数是数组吗?我做错了什么

#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();
  }
}