有人比我更聪明请向我解释为什么以下代码段出现故障?通过引用分配内存没有问题,但是一旦我尝试分配任何内容或通过引用释放,就会发生段错误。
我确信我错过了关于指针和通过引用传递的一些基本概念,希望可以解决一些问题。
#include <stdlib.h>
#include <stdio.h>
void allocateMatrix(float ***);
void fillMatrix(float ***);
void freeMatrix(float **);
int main() {
float **matrix;
allocateMatrix(&matrix); // this function calls and returns OK
fillMatrix(&matrix); // this function will segfault
freeMatrix(matrix); // this function will segfault
exit(0);
}
void allocateMatrix(float ***m) {
int i;
m = malloc(2*sizeof(float*));
for (i = 0; i < 2; i++) {
m[i] = malloc(2*sizeof(float));
}
return;
}
void fillMatrix(float ***m) {
int i,j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 2; j++) {
(*m)[i][j] = 1.0; // SEGFAULT
}
}
return;
}
void freeMatrix(float **m) {
int i;
for (i = 0; i < 2; i++) {
free(m[i]); // SEGFAULT
}
free(m);
return;
}
答案 0 :(得分:8)
这里有一组问题:
void allocateMatrix(float ***m) {
int i;
m = malloc(2*sizeof(float*));
for (i = 0; i < 2; i++) {
m[i] = malloc(2*sizeof(float));
}
return;
}
您需要分配到*m
以将信息返回给调用代码,并且您还需要在循环中分配到(*m)[i]
。
void allocateMatrix(float ***m)
{
*m = malloc(2*sizeof(float*));
for (int i = 0; i < 2; i++)
(*m)[i] = malloc(2*sizeof(float));
}
其他功能至少有可能正常。 fillMatrix()
被正确编写和调用,但可以通过从指针中丢失第三个*
来简化它:
void fillMatrix(float **m)
{
for (int i = 0; i < 2; i++)
{
for (int j = 0; j < 2; j++)
m[i][j] = 1.0;
}
}
建议将三指针传递给freeMatrix()
,这样就可以将调用函数中的指针归零:
void freeMatrix(float ***m)
{
for (int i = 0; i < 2; i++)
free((*m)[i]);
free(*m);
*m = 0;
}
然后呼叫变为:
allocateMatrix(&matrix);
fillMatrix(matrix);
freeMatrix(&matrix);
答案 1 :(得分:3)
善用间接。只是尝试与格式保持一致。它提高了可读性并减少了错误。 e.g。
函数调用:
allocateMatrix &matrix
fillMatrix &matrix
freeMatrix &matrix
声明
void allocateMatrix float ***m
void fillMatrix float ***m
void freeMatrix float ***m
处理
(*m)[i] = malloc(2 * sizeof(float))
(*m)[i][j] = 1.0
free (*m)[i]
答案 2 :(得分:0)
从函数返回指针可能是分配内存的更好方法:
float **allocateMatrix() {
int i;
float **m;
m = malloc(2*sizeof(float *));
for (i = 0; i < 2; i++) {
m[i] = malloc(2*sizeof(float));
}
return m;
}
int main() {
float **m;
m = allocateMatrix();
/* do other things
fillMatrix(matrix);
freeMatrix(&matrix);
*/
}