从函数返回字符串有问题

时间:2011-04-13 21:25:44

标签: c

我在使用C语言中的字符串基本原则时遇到了问题。 我有一个功能:

char *editStr(char *str) {
char new[strlen(str)];
... do some editing ...
return new;
}

如何返回名为“new”的字符数组。据我所知,函数的返回值是一个char *,这意味着它要求指向字符串的第一个字符。 现在,我想问题是我正在返回一个数组字符。我试图返回指向“new”中第一个字符的指针,但这似乎也不起作用。 我试过“return * new [0]”。 我的字符串知识很糟糕。

7 个答案:

答案 0 :(得分:2)

您将返回指向您在堆栈上创建的内容的指针。你不能这样做。

你需要从堆中malloc()内存并返回它(然后再free()

char *editStr(char *str) {
    char *newArray = malloc(strlen(str) +1);
     ... do some editing ...
     return newArray;
}

编辑:因为我忘了为字符串终止符添加1。如果您想要使用原始字符串的副本,也可以使用strdup()

答案 1 :(得分:2)

此处存在各种问题,但return new;的数组/指针问题不是其中之一。

首先,你想:

char new[strlen(str) + 1];

这样你就有足够的空间来容纳null终结符。

你的new被分配在堆栈上,所以返回它只会引起悲伤和混乱;你想要:

char *new = malloc(strlen(str) + 1);

,以便在函数返回时内存仍然有效。

就你的真实问题而言,C中的数组是第一个元素的地址,因此你的return new;很好(受上面提到的堆栈与堆问题的影响)。 C数组在一滴帽子处衰减为指针,因此当声明函数返回指针时,您不必担心返回数组。

答案 2 :(得分:1)

这就是我所看到的:

  1. “new”一词是C ++关键字。不要用它来命名变量
  2. 如果要编辑字符串,请直接编辑str。
  3. 如果您需要制作副本,请使用malloc(strlen(str))分配额外的内存。

答案 3 :(得分:0)

new变量是堆栈分配的,你不能返回堆栈变量的引用。

char *editStr(char *str) {
     char new[strlen(str)];
     ... do some editing ...
     return new;
} // At this point, Unwinding of stack begins.
  // new is on stack and the memory allocated to it is deallocated.
  // So, the returned reference is only pointing to garbage.

相反,一旦完成,你应该使用malloc和free

char *new = malloc( strlen(str) + 1 ) ; // +1 for the the termination character

答案 4 :(得分:0)

This文章介绍了您正在解决的问题。

在C中返回指向数组的指针的最佳方法是这样的:

char *getArr()
    {
    char *retbuf = malloc(25);
    if(retbuf == NULL)
        return NULL;
    return retbuf;
    }

答案 5 :(得分:0)

当您创建一个普通的C数组时,它只会存在于您创建它的范围内(在本例中为函数editStr()),并且一旦从该函数返回就会被销毁。因此,如果您返回数组指针,它将变得无用,如果您尝试使用它,您的程序很可能会崩溃。

相反,您应该使用malloc()动态分配数组。它很容易使用:

 char *a = (char*) malloc(sizeof(char) * 5);

这将创建一个可以使用的5 char个数组,甚至可以在函数之间传递。但是,当它们超出范围时,它们不会自动被破坏,因此当您完成指针时,需要使用free(a)手动破坏它们,否则最终会导致内存泄漏。

另见:

答案 6 :(得分:0)

如果您在单线程环境中工作并且立即使用该值,则可以使内部缓冲区保持静态,即使在退出该函数后它也可用:

 char *editStr(char *str) {
     static char new[strlen(str)];
     ... do some editing ...
     return new;
 }

您还可以使用普通的旧sprintf样式:将指向缓冲区的指针传递给函数并将其填充到内部。

 int editStr(char *str, char *new, int new_size) {
     ... do some editing ...
     return 0; //can return error
 }