【问题标题】:String returned from function contains garbage [duplicate]从函数返回的字符串包含垃圾[重复]
【发布时间】:2020-01-08 17:48:25
【问题描述】:

我希望函数lch()返回一个可以在函数外使用的字符串。
这是我写的代码,但它似乎不起作用:

char *lch(char *ch,int n){ 
    char c[n];
    for(int i=0;i<n;i++){
            c[i] = *ch;
    }
    puts(c); // check output string inside function 
    return c;
}

char str[100],*p;

main(){
    p = lch("a",20);
    puts(p); // check output outside function
}

我对字符串以及如何将它们传递给函数感到困惑。
我希望输出字符串在两次调用 puts() 时都相同。
我该怎么办?

就是上面代码的结果:

aaaaaaaaaaaaaaaaaaaa               // inside the function 
                      ¢ÞêÊ·      // outside the function

【问题讨论】:

  • 这里有几个问题,它们都是许多现有问题的重复。您可能想研究为什么 1) 返回一个本地定义的数组,2) 不要用 '\0' 字符终止您的字符串。
  • 请注意,这不会作为重复关闭以阻止您;重复的链接旨在回答您的问题。如果重复问题的答案不能回答您的问题,请编辑您的问题,它可能会重新打开。

标签: c arrays pointers


【解决方案1】:

首先,返回本地分配的存储是行不通的。您必须返回动态分配的存储空间,并具有适当的大小以容纳空终止符:

char *c = malloc(n+1);
/* ... */
/* end of program: */
free(p);

其次,你想将一个字符传递给你的函数,而不是一个字符串:

char *lch(char ch,int n){
/* ... */
    c[i] = ch;
/* ... */
p = lch('a', 20);

第三,你必须以空值结束你的字符串:

int i;
for(i=0;i<n;i++){
        c[i] = ch;
}
ch[i] = '\0';
puts(c); //check output string inside function 

这是动态分配的存储方法:

#include <stdlib.h>
#include <stdio.h>

char *lch(char ch,int n){ 
    char *c = malloc(n+1);
    int i;
    for(i=0;i<n;i++){
            c[i] = ch;
    }
    c[i] = '\0';
    puts(c); //check output string inside function 
    return c;
}

char *p;

int main(void){
    p = lch('a',20);
    puts(p); //check output outside function
    free(p);
    return 0;
}

这也修复了main的声明和返回类型(main应该是int main(void)int main(int argc, char **argv)),删除不需要的变量str,并添加需要的#includes。

【讨论】:

  • @tonga 查看编辑。
【解决方案2】:

你的代码没有做你期望它做的事情的原因是因为函数中的字符串是在堆栈上分配的,这意味着一旦你退出函数,它的内存就会被清理。

这意味着指针p在调用lch()后指向垃圾值。

另外,你不能声明一个大小不是常数值的数组,所以行:

char c[n];

根本行不通。

要解决这个问题,您需要使用 ma​​lloc(3) 动态分配字符串:

char* lch(char ch, int n)
{ 
    char * c;

    /* Allocate n bytes of memory for the string */
    c = malloc(n + 1);
    if (NULL == c)
    {
        /* Failed to allocate memory, exit the function */
        return c;
    }

    for(int i = 0; i < n; i++)
    {
        c[i] = ch;
    }
    /* Add a terminating null byte (to make it a string) */
    c[i] = '\0'; 

    puts(c);
    return c;
}

int main(void)
{
    char * p;
    p = lch('a', 20);
    puts(p);

    /* Free the string from the memory */
    free(p);

    return 0;
}

我对代码添加了一些修复,但您需要查看的主要内容是 ma​​lloc(3) 的使用。

我为字符串动态分配了n+1字节的内存,然后将数据写入字符串(加上一个'\0'),当函数退出时内存依然可用并且不会被破坏。 需要调用 free 来释放我们分配的内存。

您可以在此处阅读有关 ma​​lloc(3) 的更多信息:https://linux.die.net/man/3/malloc

【讨论】:

  • char c[n]; 在 C11(我认为?)及更高版本中工作。它被称为“变长数组”,简称 VLA..
猜你喜欢
  • 2013-10-30
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 2013-02-07
  • 1970-01-01
  • 2023-03-17
  • 1970-01-01
相关资源
最近更新 更多