首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何从函数返回字符串数组

如何从函数返回字符串数组
EN

Stack Overflow用户
提问于 2010-11-03 16:51:58
回答 6查看 48.7K关注 0票数 13
代码语言:javascript
复制
char * myFunction () {

    char sub_str[10][20]; 
    return sub_str;

} 

void main () {

    char *str;
    str = myFunction();

}

错误:从不兼容的指针类型返回

谢谢

EN

回答 6

Stack Overflow用户

发布于 2012-07-18 22:21:30

对于刚开始编程的程序员来说,“栈”或“堆”的概念可能有点混乱,特别是如果您已经开始使用Ruby、Java、Python等高级语言进行编程。

考虑一下:

代码语言:javascript
复制
char **get_me_some_strings() {
  char *ary[] = {"ABC", "BCD", NULL};
  return ary;
}

编译器将正确地发出关于试图返回局部变量的地址的投诉,而您在尝试使用返回的指针时肯定会得到一个分段错误。

和:

代码语言:javascript
复制
char **get_me_some_strings() {
  char *ary[] = {"ABC", "BCD", NULL};
  char **strings = ary;
  return strings;
}

将关闭编译器,同时仍然得到相同的讨厌的分段错误。

为了让除了狂热者之外的每个人都高兴,你应该做一些更复杂的事情:

代码语言:javascript
复制
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char **get_me_some_strings() {
  char *ary[] = { "ABC", "BCD", NULL };
  char **strings = ary; // a pointer to a pointer, for easy iteration
  char **to_be_returned = malloc(sizeof(char*) * 3);
  int i = 0;
  while(*strings) {
    to_be_returned[i] = malloc( sizeof(char) * strlen( *strings ) );
    strcpy( to_be_returned[i++], *strings);
    strings++;
  }
  return to_be_returned;
}

现在使用它:

代码语言:javascript
复制
void i_need_me_some_strings() {
  char **strings = get_me_some_strings();
  while(*strings) {
    printf("a fine string that says: %s", *strings);
    strings++;
  }
}

只要记住,当你完成后释放分配的内存,因为没有人会为你做这件事。这适用于所有指针,而不仅仅是指向指针的指针!(我想)。

要更好地理解这一切,您可能还需要阅读以下内容:What and where are the stack and heap?

票数 8
EN

Stack Overflow用户

发布于 2010-11-03 16:56:56

原因:

您需要返回类型为char(*)[20]。但即使在这种情况下,您也不希望从函数返回指向本地对象的指针。

执行以下操作:

使用malloc分配sub_str,并返回char**

票数 2
EN

Stack Overflow用户

发布于 2014-10-27 09:43:53

编译器错误的原因很简单,但不是您真正想要做的事情的答案。您声明函数返回char *,而返回char **。

在不知道你正在做什么的细节的情况下,我将假设以下两件事中的一件是真的:

1)该函数的作用是创建和返回字符串数组。2)该函数对字符串数组执行一些操作。

如果#1为真,则需要几个malloc调用才能完成此工作(实际上只需两个调用即可完成,但为了简单起见,我将使用几个)。

如果你不知道数组应该有多大,你的函数声明应该是这样的:

代码语言:javascript
复制
char ** allocateStrings ( int numberOfStrings, int strLength );

这样做的原因是因为您实际上返回了一个指向指针数组的指针,并且您需要知道有多少个字符串以及每个字符串有多长。

代码语言:javascript
复制
char ** allocateStrings ( int numberOfStrings, int strLength )
{
    int i;

    //The first line is allocating an array of pointers to chars, not actually allocating any strings itself
    char ** retVal = ( char ** ) malloc ( sizeof ( char * ) * numberOfStrings );

    //For each string, we need to malloc strLength chars
    for ( i = 0; i < numberOfStrings; i ++ )
    {
        //Allocate one extra char for the null pointer at the end
        retVal [ i ] = ( char * ) malloc ( sizeof ( char ) * ( strLength + 1 ) );
    }

    return retVal;
}

正如其他人指出的那样,最好的做法是让分配的东西也做释放分配。因此需要一个清理函数。

代码语言:javascript
复制
void cleanupStrings ( char ** strArray, int numberOfStrings )
{
    int i;

    for ( i = 0; i < numberOfStrings; i ++ )
    {
        //Should be checking to see if this is a null pointer.
        free ( strArray [ i ] );
    }

    //Once the strings themselves are freed, free the actual array itself.
    free ( strArray );
}

现在,请记住,一旦调用了cleanup函数,您就不再有权访问数组。尝试仍然使用它很可能会导致您的应用程序崩溃。

如果#2为true,则需要分配字符串、处理字符串并清除它们。你应该使用上面的两个函数来分配/释放你的字符串,然后使用第三个函数来处理它们。

代码语言:javascript
复制
void processStrings ( char ** strArray, int numberOfStrings, int strLength );
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4085372

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档