我制作了一个函数,该函数返回指向新创建的矩阵的指针。现在,我希望该函数返回类型为status_t
的错误代码,而不是指针。为此,必须添加另一个指针级别,并且必须通过引用返回矩阵。但是,我不明白为什么会出现细分错误。这是我的工作代码(a)和失败的尝试(b)的一部分:
(a)
int **create_matrix(size_t dimension) {
int **p;
size_t e;
size_t h;
if (dimension == 0)
return NULL;
for (h = 0; h < dimension; ++h) {
if ((p[h] = malloc(dimension * sizeof(int))) == NULL) {
for (e = h; e >= 0; --e) {
free(p[e]);
p[e] = NULL;
} <-------- missing closing brace
return NULL;
}
}
return p;
}
(b)
status_t create_matrix(size_t dimension, int ***p) {
size_t e;
size_t h;
if (p == NULL)
return ERROR_NULL_POINTER;
for (h = 0; h < dimension; ++h) {
if (((*p)[h] = malloc(dimension * sizeof(int))) == NULL) {
for (e = h; e >= 0; --e) {
free((*p)[e]);
(*p)[e] = NULL;
} <-------- missing closing brace
return ERROR_NO_MEMORY;
}
}
}
谢谢!
答案 0 :(得分:4)
(a)并非完全“有效”:
一方面,它的{
比}
多,因此甚至无法编译。您可能忘记了终止外部for
循环。
int ** p;
...
if ((p[h]=...))
这会在初始化之前取消引用p
。使用未初始化变量的值是未定义的行为。您需要先为p
分配一些内容(可能是通过动态分配另一个数组)。
要确定版本(b)是否存在相同的问题,我们必须查看调用代码,但猜测它也是UB。
内循环还有另一个问题:
for (e = h; e >= 0; --e)
e
是size_t
,它是无符号整数类型,因此条件e >= 0
始终为真。
您使用什么编译器(和编译器选项)?有了gcc -Wall -Wextra -pedantic
,我得到warnings for both of these。
固定版本如下:
int **create_matrix(size_t dimension) {
int **p = calloc(dimension, sizeof *p);
if (!p) {
return NULL;
}
for (size_t i = 0; i < dimension; i++) {
if (!(p[i] = calloc(dimension, sizeof *p[i]))) {
while (i--) {
free(p[i]);
}
free(p);
return NULL;
}
}
return p;
}
然后可以将版本(b)定义为
status_t create_matrix_2(size_t dimension, int ***p) {
if (!p) {
return ERROR_NULL_POINTER;
}
if (!(*p = create_matrix(dimension))) {
return ERROR_NO_MEMORY;
}
return SUCCESS_OR_SOMETHING;
}
我不确定您想要获得成功的回报是什么;您的版本(b)在那里缺少返回声明。