[英]Return an array of strings from a function
I need to return a char**
but when I try to do this, the compiler tells me that I want to return the address of a local variable.我需要返回一个
char**
但是当我尝试这样做时,编译器告诉我我想返回一个局部变量的地址。 How can I do that?我怎样才能做到这一点? I know that I should allocate space for this variable but how?
我知道我应该为这个变量分配空间但是如何? Here is my code, but the second
printf
doesn't appear and the function returns nothing:这是我的代码,但是第二个
printf
没有出现,并且 function 什么也不返回:
char** parse_cmd(const char* cmdline) {
char** arguments = (char**)malloc(100);
int i;
int j=0, k=0;
printf("%s\n", cmdline);
for(i=0; i<100; i++) {
arguments[i] = malloc(100);
}
for(i = 0; i < strlen(cmdline); i ++) {
if(cmdline[i] != ' ') {
arguments[j][k] = cmdline[i];
k++;
} else {
arguments[j][k] = '\0';
j++;
k = 0;
}
}
printf("%s\n", arguments[1]);
return arguments;
}
You need to do multiple allocations.您需要进行多次分配。 The first for the
char**
and then for each of the char*
.第一个用于
char**
,然后用于每个char*
。 Eg something like例如像
char **args = (char**)malloc(100);
int i;
for (i=0; i<100; i++)
args[i] = malloc(100);
// Rest of program
return args;
Here's the code I assembled - and tested.这是我组装和测试的代码。 It uses dynamic memory allocation for both the
argv
argument list and for each argument as it is assembled.它使用动态 memory 分配
argv
参数列表和组装时的每个参数。 The function release_cmd()
releases the allocated space. function
release_cmd()
释放分配的空间。 The function cleanup()
is internal and releases allocated space on a failure, before returning a null double-pointer. function
cleanup()
是内部的,在失败时释放分配的空间,然后返回 null 双指针。 This simplifies the error handling.这简化了错误处理。 There's a minimal test harness in the
prompt()
function and main()
. prompt()
function 和main()
中有一个最小的测试工具。 I haven't run in under valgrind
, but the MacOS X implementation of malloc()
quite often spots problems so I'm moderately confident there's no gross memory abuse - but there could be an off-by-one leak.我没有在
valgrind
下运行,但是malloc()
的 MacOS X 实现经常会发现问题,所以我有信心没有严重的 memory 滥用 - 但可能存在一次泄漏。 I haven't tested the cleanup()
code by faking an allocation failure.我没有通过伪造分配失败来测试
cleanup()
代码。
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void release_cmd(char **argv)
{
for (size_t i = 0; argv[i] != 0; i++)
free(argv[i]);
free(argv);
}
static char **cleanup(size_t argc, char **argv)
{
argv[argc] = 0;
release_cmd(argv);
return 0;
}
char **parse_cmd(const char* cmdline)
{
size_t argc = 2;
char **argv = malloc(argc * sizeof(char *));
if (argv == 0)
return 0;
size_t j = 0; // Index into argv
size_t len = strlen(cmdline);
for (size_t i = 0; i < len; i++)
{
while (isspace(cmdline[i]))
i++;
if (cmdline[i] == '\0')
break;
if (j > argc - 2)
{
size_t newc = (argc * 2);
char **newv = realloc(argv, newc * sizeof(char *));
if (newv == 0)
return cleanup(argc, argv);
argv = newv;
argc = newc;
}
size_t argl = 2; // Length of argument string
argv[j] = malloc(argl);
size_t k = 0; // Index into argv[j]
while (cmdline[i] != '\0' && !isspace(cmdline[i]))
{
if (k > argl - 2)
{
size_t newl = argl * 2;
char *news = realloc(argv[j], newl);
if (news == 0)
return cleanup(argc, argv);
argv[j] = news;
argl = newl;
}
argv[j][k++] = cmdline[i++];
}
argv[j][k] = '\0';
argv[j] = realloc(argv[j], k+1); // Shrink to fit!
j++;
}
argv[j] = 0;
argv = realloc(argv, (j+1)*sizeof(*argv)); // Shrink to fit!
return argv;
}
static int prompt(const char *prompt, char *buffer, size_t bufsiz)
{
printf("%s", prompt);
return (fgets(buffer, bufsiz, stdin) != 0);
}
int main(void)
{
char line[1024];
while (prompt("cmd? ", line, sizeof(line)) != 0)
{
char **argv = parse_cmd(line);
char **args = argv;
while (*args)
puts(*args++);
release_cmd(argv);
}
putchar('\n');
return 0;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.