Arrays 从函数返回字符串但打印空值,原因是什么?

Arrays 从函数返回字符串但打印空值,原因是什么?,arrays,c,string,Arrays,C,String,我试图从str函数返回一个字符串,但它打印(null) #包括 char*str() { char hi[10]=“返回此项”; 返回hi; } void main() { printf(“%s”,str()); } #包括 #包括 char*str(){ //malloc用于分配内存 char*hi=(char*)malloc(sizeof(char)*20); char ch[]=“返回此\0”; 对于GCC中的(int i=0;i),至少您的代码编译时会出现以下警告: main.c:12:

我试图从str函数返回一个字符串,但它打印(null)

#包括
char*str()
{
char hi[10]=“返回此项”;
返回hi;
}
void main()
{
printf(“%s”,str());
}
#包括
#包括
char*str(){
//malloc用于分配内存
char*hi=(char*)malloc(sizeof(char)*20);
char ch[]=“返回此\0”;

对于GCC中的(int i=0;i),至少您的代码编译时会出现以下警告:

main.c:12:19: warning: initializer-string for array of chars is too long                                                                        
main.c:13:12: warning: function returns address of local variable [-Wreturn-local-addr]  

这或多或少是对你的问题的直接回答。如果你没有得到这些警告,考虑你使用的编译器,对于GCC,我建议至少<代码> -WalthWrase<代码>——这将输出最有用的警告,而不是迂腐的,并且警告那些错误,这样会阻止成功编译直到你修复。嗯

您返回的是一个指向本地自动变量的指针,该变量在函数返回后不再在作用域中,因此结果未定义。您还尝试使用保留的更多字符初始化数组

编译器在这里所做的是给无效的初始化器,它将
hi
的地址设置为null,并且
printf
通过打印
(null)来处理null指针
。这是特定于编译器和C库的行为-在其他情况下可能会发生一些不同的情况。更隐晦的是,如果您的初始化器不是无效的(通过变短),它很可能看起来是有效的,您可能从来没有问过这个问题,但它仍然是不正确的,在更复杂的代码中,它可能在某个时候导致可观察到的错误行为

在这种情况下,您可以执行以下任一操作:

const char* str()
{
    static const char* hi = "return this";
    return hi;
}
最合适的解决方案(以上内容并非详尽无遗)取决于您实际想要做什么,因为每个解决方案在语义上都不同,而且单独使用此函数几乎不实用。它需要一个具体的实际示例来给出最佳建议。

读取或访问函数外部的变量

您的代码溢出,请阅读

也读

#包括
char*str()
{
静态字符hi[]=“返回此”;
返回hi;
}
int main()
{
printf(“%s”,str());
返回0;
}

问题在于字符数组的范围

此问题的解决方案是使该变量的地址对调用方函数可见

i、 e。 最简单的解决方案之一是在str()函数的hi变量声明部分使用下面的行。 即 静态字符hi[10]=“返回th”

在宣言中。 通过这种方式,您不需要更改此程序中的任何内容,但在整个程序中,此变量将在整个执行过程中可见/可访问

#include"stdio.h"

char* str() {
    static char hi[10] = "return th";
    return hi; 
}

int main() {
    printf("%s", str());
    return 0;
}

由于hi在str的作用域内,因此将其地址返回到作用域外是没有意义的。hi变量的作用域被限制为
str函数
。因此,当从str函数中执行时,堆栈被清除,因此分配给hi的内存也被清除,因为它给出了分段错误。Yuk。只需切换另一个(内存泄漏)的问题。
sizeof(char)
定义为1,所以
sizeof(char)*20
与这里的20
相比没有任何好处。你对自己答案的评论是答案的一部分,应该出现在答案中。没有解释就扔代码并不是问题的答案,即使它是问题的解决方案。你的解决方案如何使变量“可见/可访问”在整个项目中?一个变量有作用域和生存期,通过声明一个局部的
静态的
,它有一个程序持续时间的生存期,但它不再是一个非静态变量,因为它有相同的作用域。您应该编辑答案来添加解释性代码,而不是在注释中添加它。注释不是程序的一部分swer和肯定不适合发布代码。初始化器太大不会导致溢出,因为它是在编译时检查的,这就是为什么它会打印
(null)
-尽管它仍然是未定义的行为。如果缩短初始化器,它可能会(在这个简单的情况下很可能会)似乎可以工作,但它仍然是错误的。不确定这一点,但它仍然不是正确的方法,对吗?这是正确的。我描述的行为是我在gdbonline(GCC)…YMMV经验确定的。一个实现差的编译器很可能会溢出缓冲区。
const char* str()
{
    static const char* hi = "return this";
    return hi;
}
const char* str()
{
    static const char hi[] = "return this";
    return hi;
}
char* str( char* str, int maxlen )
{
    str[maxlen] = '\0' ;
    return strncpy( str, "return this", maxlen - 1 ) ;
}

void main()
{
    char* buffer[32] ;
    printf("%s", str(buffer, sizeof(buffer));
}
#include<stdio.h>
char* str()
{
    static char hi[] = "return this";
    return hi;
}

int main()
{
    printf("%s", str());
    return 0;
}
#include"stdio.h"

char* str() {
    static char hi[10] = "return th";
    return hi; 
}

int main() {
    printf("%s", str());
    return 0;
}