从函数返回 char[]/string [重复]

Posted

技术标签:

【中文标题】从函数返回 char[]/string [重复]【英文标题】:Return char[]/string from a function [duplicate] 【发布时间】:2013-01-03 05:11:19 【问题描述】:

我对 C 语言编码相当陌生,目前我正在尝试创建一个函数,该函数返回一个 c 字符串/字符数组并分配给一个变量。

到目前为止,我观察到返回 char * 是最常见的解决方案。所以我尝试了:

char* createStr() 
    char char1= 'm';
    char char2= 'y';
    char str[3];
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';
    char* cp = str;
    return cp;

我的问题是如何使用返回的 char* 并将它指向的 char 数组分配给 char[] 变量?

我试过了(都导致 noob-drowning 错误):

    char* charP = createStr(); char myStr[3] = &createStr(); char* charP = *createStr();

【问题讨论】:

更好的讨论,即使它较新 【参考方案1】:

请注意,您并未动态分配变量,这几乎意味着函数中 str 内的数据将在函数结束时丢失。

你应该有:

char * createStr() 

    char char1= 'm';
    char char2= 'y';

    char *str = malloc(3);
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';

    return str;


然后,当您调用函数时,将接收数据的变量的类型必须与函数返回的类型匹配。所以,你应该有:

char *returned_str = createStr();

值得一提的是,必须释放返回值以防止内存泄漏。

char *returned_str = createStr();

//doSomething
...

free(returned_str);

【讨论】:

sizeof(char) 保证为 1 并且没有理由对malloc 返回进行类型转换 @Aniket +1 感谢您的评论。有时朋友告诉我,但我想我当时不明白这个问题,后来又没有想到这个问题:D【参考方案2】:

如果你想从一个函数返回一个char*,确保你malloc()它。堆栈初始化的字符数组在返回时没有任何意义,因为在从该函数返回后访问它们是未定义的行为。

改成

char* createStr() 
    char char1= 'm';
    char char2= 'y';
    char *str = malloc(3 * sizeof(char));
    if(str == NULL) return NULL;
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';
    return str;

【讨论】:

值得一提的是,必须释放返回值以防止内存泄漏。 char* astr = createStr(); doSomething(astr); free(astr); 这就是我要找的!我有点困惑,因为从函数返回指针可能会导致内存泄漏。你的回答解决了我的问题。所以最终释放 char *astr 持有的内存。 (例如,在 Java 中。我知道这不是问题,因为垃圾收集器会小心处理)【参考方案3】:
char* charP = createStr();

如果你的函数是正确的,那就是正确的。不幸的是,您正在返回指向函数中局部变量的指针,这意味着一旦函数返回,它就是指向未定义数据的指针。您需要对函数中的字符串使用诸如 malloc 之类的堆分配,以使您返回的指针具有任何意义。那你需要记得稍后释放它。

【讨论】:

【参考方案4】:

您可以在方法中使用静态数组,以避免函数结束时丢失数组:

char * createStr() 

    char char1= 'm';
    char char2= 'y';

    static char str[3];  
    str[0] = char1;
    str[1] = char2;
    str[2] = '\0';

    return str;

编辑: 正如 Toby Speight 所提到的,这种方法不是线程安全的,并且调用该函数会导致数据覆盖,这在某些应用程序中是不需要的。因此,您必须在从函数返回后立即将数据保存在缓冲区中。 (但是因为它不是线程安全的方法,在某些情况下并发调用仍然会出现问题,为了防止这种情况你必须使用锁。进入函数时捕获它并在复制完成后释放它,我不喜欢使用这个方法,因为它混乱且容易出错。)

【讨论】:

可能值得一提的一些缺点(所有调用共享相同的存储,因此调用会覆盖以前的结果,并且没有什么是线程安全的)。【参考方案5】:

包含“string.h”使事情变得更容易。解决问题的更简单方法是:

#include <string.h>
    char* createStr()
    static char str[20] = "my";
    return str;

int main()
    char a[20];
    strcpy(a,createStr()); //this will copy the returned value of createStr() into a[]
    printf("%s",a);
    return 0;

【讨论】:

为什么要复制? char *a = createStr(); 也一样。 是的,你也可以使用它,这样可以节省一些内存,只是他要求一种方法来“将它(函数)指向的 char 数组分配给 char[] 变量”所以我就这么告诉他了。

以上是关于从函数返回 char[]/string [重复]的主要内容,如果未能解决你的问题,请参考以下文章

从函数返回字符串 [char 指针] [重复]

如何从string类型的变量 返回一个char* 类型

警告:函数返回局部变量的地址 [默认启用] [重复]

strcpy,strlen函数和string类原型

将 std::string_view 返回到 const char * [重复]

VS2017中遇到不存在从string到const char*的转换函数的解决方法