【发布时间】:2020-11-25 14:52:25
【问题描述】:
我有一个函数,它返回一个指向字符指针的指针 (char**)。该函数有 2 个参数
-
int* num_paths:指向整数的指针,表示要返回的字符串数。 -
int* errno:指向整数的指针以指示错误代码。这可以包含不同的值,因此我不能简单地检查是否在出现错误时返回NULL。
下面编写了一些示例代码(为简单起见,省略了大部分错误检查):
char** get_paths(int* num_paths, int* errno) {
char* path1 = NULL;
char* path2 = NULL;
char** paths = NULL;
if(errno == NULL) {
printf("Set errno in case of error, but cannot dereference NULL pointer\n");
goto exit;
}
path1 = calloc(1, strlen("foo") + 1);
path2 = calloc(1, strlen("bar") + 1);
strcpy(path1, "foo");
strcpy(path2, "bar");
*num_paths = 2;
paths = calloc(1, *num_paths*sizeof(char *));
paths[0] = path1;
paths[1] = path2;
*errno = 0;
exit:
return paths;
}
int main(void) {
char** paths = NULL;
int num_paths = 0;
int errno = 0;
paths = get_paths(&num_paths, &errno);
if(errno != 0) {
return -1;
}
for(int i = 0; i < num_paths; i++) {
printf("%s\n", paths[i]);
free(paths[i]);
}
free(paths);
}
我遇到的问题是,如果 NULL 指针作为 errno 的参数传递,我无法设置错误代码。您可以争辩说这是一个用户错误,但我仍然希望首先避免这种情况。
所以我的问题是:我可以重写我的get_paths 函数,使其返回一个整数作为错误代码,但也可以通过函数参数返回一个char**,而不使用char***,如下例所示:
int get_paths_3(char*** paths, int* num_paths) {
char* path1 = NULL;
char* path2 = NULL;
path1 = calloc(1, strlen("foo") + 1);
path2 = calloc(1, strlen("bar") + 1);
strcpy(path1, "foo");
strcpy(path2, "bar");
*num_paths = 2;
*paths = calloc(1, *num_paths*sizeof(char *));
(*paths)[0] = path1;
(*paths)[1] = path2;
return 0;
}
【问题讨论】:
-
如果 that 指针也是
NULL,则无法设置路径数。我不明白你为什么不能记录函数:NULL指针参数不允许。 -
“通过函数参数返回
char**”的正确方法是使用char***参数。有很多方法可以设计这个函数,但设计选择很大程度上决定了函数签名需要什么。 -
我不会使用
errno作为变量名。标准的<errno.h>标头(从许多其他地方间接包含)#define-s 它作为一个宏。 -
您可以将指针和整数都包装在
struct中并返回。 -
一般来说,我会将诸如“如果将 NULL 作为参数传递给错误”之类的琐碎事情的错误处理工作交给调用者。只需记录该函数:“如果您将 NULL 传递给此参数,那么您就是 f****d”。应在调用方进行各种此类健全性检查和防御性编程。
标签: c pointers char return-value dynamic-memory-allocation