c - 如何将 char** 作为函数参数返回
问题描述
我有一个函数,它返回一个指向 chars ( 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**
通过函数参数返回 a 而无需诉诸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;
}
解决方案
这几乎是唯一可以使用“三星”指针的情况。在 API 设计中为错误代码保留返回值是相当普遍的做法,因此这种情况并不少见。
有替代品,但可以说它们并没有好多少。void*
您可以滥用可以转换为/从的事实,char**
但它并没有更漂亮且类型安全性更低:
// not recommended
int get_paths_4 (void** paths, size_t* num_paths)
{
char* path1 = calloc(1, strlen("foo") + 1);
char* path2 = calloc(1, strlen("bar") + 1);
strcpy(path1, "foo");
strcpy(path2, "bar");
*num_paths = 2;
char** path_array;
path_array= calloc(1, *num_paths*sizeof(char *));
path_array[0] = path1;
path_array[1] = path2;
*paths = path_array;
return 0;
}
...
void* vptr;
size_t n;
get_paths_4 (&vptr, &n);
char** paths = vptr;
for(size_t i=0; i<n; i++)
{
puts(paths[i]);
}
一个更合理的选择可能是将所有参数包装成一个struct
类型并将该类型作为指针传递。
推荐阅读
- java - 如何使用依赖注入构建简单的 Java Rest API 服务
- javascript - p5.js 中的 setup() 函数是如何工作的?
- c - 如何识别图像来自点阵打印机
- php - 如何在 PHP 中使用 foreach 循环解决“通知:数组到字符串转换”错误?
- hibernate - 将 Hibernate 3.3.0 迁移到 5.2
- javascript - 使用新版本的 Firebase 不断收到 Uncaught TypeError
- httpie - 如何使用httpie发送未命名的JSON数组
- r - 如何使用 R 中的 plot_grid() 函数绘制多个 seqplots(TraMineR 包)?
- javascript - 这个简单的测试有什么问题?
- swagger - 如何用值描述模式对象?