简体   繁体   English

功能内存分配问题

[英]Issue with function memory allocation

After I compile and run the function, I get a segmentation fault: 11. I believe malloc should be performed correctly so I am not sure why I get a seg fault. 编译并运行函数后,我遇到了分段错误:11.我相信应该正确执行malloc,所以我不确定为什么会出现seg错误。 Any insights would be greatly appreciated! 任何见解将不胜感激!

 typedef struct matrix matrix; struct matrix { unsigned int n_rows; unsigned int n_cols; float **entries; }; //refer to matrix.h matrix *matrix_zero(unsigned int n_rows, unsigned int n_cols){ struct matrix* new = (struct matrix*)malloc(sizeof(struct matrix)); new->entries = malloc(n_rows * n_cols * sizeof(float)); new->n_rows=n_rows; new->n_cols=n_cols; for(int x = 0; x < n_rows; x++){ for(int y = 0; y < n_cols; y++){ new->entries[x][y] = 0; } } return new; } /* main: run the evidence functions above */ int main(int argc, char *argv[]) { struct matrix* test1 = matrix_zero(3,3); // matrix_show(test1); } 

The problem appears to be in your allocation for matrix->entries . 问题似乎出在您对matrix->entries分配中。 The struct defines a pointer to a pointer, but you allocate a float pointer float* vs float** . 该结构定义了一个指向指针的指针,但是您分配了一个float指针float* vs float** You need to allocate n_rows number of float* and each of those needs to point to an allocations of n_cols number of float value. 您需要分配n_rows float*并且每个都需要指向n_colsfloat值分配。 For example: 例如:

int i;
// No error checking shown here
new->entries = malloc(sizeof(float*) * n_rows);
for (i = 0; i < n_rows; i++) {
    new->entries[i] = malloc(sizeof(float) * n_cols);
}

You have allocated an array for rows by cols size, but there's no way for the compiler to know the actual row size for each row, so the notation entries[i] indeed expects a pointer to a simple array of floats, and not a bidimensional array. 您已经按cols大小为rows分配了一个数组,但是编译器无法知道每行的实际行大小,因此符号entries[i]确实希望有一个指向简单浮点数组的指针,而不是二维数组阵列。 This is one of the main differences in structure from a n-dimensional array and arrays of pointers in C. The compiler knows how to dimension it only when you fully qualify the array dimensions (as when you declare it as float entries[N][M]; --- look that you cannot use variable expressions in the dimensions, only static compile-time constants) 这是与n维数组和C语言中的指针数组在结构上的主要区别之一。仅当完全限定数组维(例如,将其声明为float entries[N][M]; --您不能在维度中使用变量表达式,只能使用静态编译时常量)

You have two approaches here: 这里有两种方法:

  • Use a single dimension array an compute the index based on the rows sizes: 使用一维数组并根据行大小计算索引:

     typedef struct matrix matrix; struct matrix { unsigned int n_rows; unsigned int n_cols; float *entries; /* we make this to point to a single array of n_rows * n_cols entries */ }; new->entries = malloc(n_rows * n_cols * sizeof(float)); new->n_rows=n_rows; new->n_cols=n_cols; for(int x = 0; x < n_rows; x++){ for(int y = 0; y < n_cols; y++){ new->entries[x * n_cols + y] = 0.0; /* entry position should be as shown */ } 
  • Use individual row arrays of n_cols entries (this has been shown in another answer by @joel already) 使用n_cols条目的单个行数组(这已经在@joel的另一个答案中显示了)

     typedef struct matrix matrix; struct matrix { unsigned int n_rows; unsigned int n_cols; float **entries; /* this time the entries field points to an array of pointers to float. */ }; new->entries = malloc(n_rows * sizeof *new->entries); /* individual cells are 'float *', not 'float' this time. */ new->n_rows=n_rows; new->n_cols=n_cols; for(int x = 0; x < n_rows; x++){ new->entries[x] = malloc(n_cols* sizeof **new->entries); /* this time float *'s are here */ for(int y = 0; y < n_cols; y++){ new->entries[x][y] = 0; /* entry position should be as shown */ } } 

Both methods have remarks: 两种方法都有说明:

  • First method requires only one malloc(3) for the entries array so this makes it easier to allocate and deallocate, but some implementations could limit the actual size of a single malloc(3) in case you want to allocate huge matrices. 第一种方法只需要一个malloc(3)用于entrys数组,因此这使得分配和取消分配更加容易,但是某些实现可能会限制单个malloc(3)的实际大小,以防您要分配巨大的矩阵。 This makes the deallocation for the whole matrix also easier. 这使得整个矩阵的重新分配也更加容易。

  • Second method only requires a malloc of n_rows pointers and n_rows mallocs of n_cols float s. 第二种方法只需要一个malloc n_rows指针和n_rows的mallocs n_cols float秒。 This will make possible to allocate huge matrices (you never allocate the whole matrix in one chunk) but you'll have to deallocate all rows first, then the array of pointers to the rows, before deallocating the matrix struct. 这将可以分配巨大的矩阵(您永远不会在一个块中分配整个矩阵),但是必须先分配所有行,然后再分配指向行的指针数组,然后再分配矩阵结构。

  • I recommend you to use malloc(n_cols * sizeof *new->entries) instead of malloc(n_cols * sizeof (float *)) , so you don't need to change this expression in case you change the definition type of new->entries . 我建议您使用malloc(n_cols * sizeof *new->entries)而不是malloc(n_cols * sizeof (float *)) ,因此,如果您更改new->entries的定义类型,则无需更改此表达式new->entries

Finally, think that there's no magic in the C language in respect of calling functions. 最后,认为C语言在调用函数方面没有魔力。 You probably erroneously assumed that making malloc( n_rows * n_cols * sizeof(float) ) converted automatically the pointer to a bidimensional array , but there's no magic there, malloc(3) is a normal C function like the ones you can write, and that's the reason it requires the actual number of bytes, and not the dimensions (in elements) of the array. 您可能错误地认为,使malloc( n_rows * n_cols * sizeof(float) )自动将指针转换为二维数组 ,但那没有什么魔术, malloc(3)是一个普通的C函数,就像您可以编写的那样,那就是原因是它需要实际的字节数,而不是数组的尺寸(以元素为单位)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM