在尝试自己学习C的同时,我遇到了这个我想要开发的简单程序。它只是试图利用指向指针数组的指针来制作类似于矩阵的东西。我在Windows上编译,当我运行它时,它只是崩溃,同时,在Linux上尝试这个代码,它说segmentation fault
,这是因为函数参数是数组吗?我在这里做错了什么?
#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");
}
}
答案 0 :(得分:1)
做的时候:
void initializeArray(float** array, int size)
{
array = malloc(size * sizeof(float*));
你没有在函数外部更改array
,因此array_1
在调用之后(像之前一样)指向NULL(并创建内存泄漏)。您需要将其返回(或将其作为三***
指针传递并将其用作*array
,但这不太方便。
float **initializeArray(int size)
{
float** array = malloc(size * sizeof(float*));
...
return array;
}
来自main:
array_1 = initializeArray(array_size);
答案 1 :(得分:0)
如果希望函数修改参数的值,则必须传递指向该参数的指针:
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
都是如此,包括指针类型。将T
替换为P *
,我们就会
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;
}
}
}
将从main
调用为:
initializeArray(&array_1, array_size);
一些建议:
首先,在调用malloc
时,将sizeof
运算符的操作数设为取消引用的目标,而不是类型名称:
ptr = malloc( N * sizeof *ptr );
在你的情况下,它将是
*array = malloc( size * sizeof **array ); // sizeof operand has one more level of
// indirection than target
和
(*array)[i] = malloc( size * sizeof *(*array)[i] );
如果您更改array
的类型,这将保护您;您不必追逐sizeof (float)
或sizeof (float *)
的每个实例并更改这些实例。
其次,你所分配的不是2D数组 - 它是一个指针数组,每个指针指向一个单独的float
数组。哪个非常好,取决于你正在做什么,只要知道行在内存中不相邻 - array[1][2]
之后的对象不将是{{1 }}。
如果您想分配连续的多维数组,您可以使用
之类的内容array[2][0]
为连续的3x3阵列留出空间。使用VLA语法,您可以编写类似
的函数float (*array)[3] = malloc( 3 * sizeof *array );