我必须在函数中malloc返回的字符串吗?

我必须在函数中malloc返回的字符串吗?,c,malloc,C,Malloc,以下程序将按预期在屏幕“Hello\nWorld\n”('\n'=行向下)上打印。但事实上,正如我所了解到的,这里有些事情并没有按应有的方式去做。“hello”和“world”字符串是在函数中定义的(因此是本地的,它们的内存在函数作用域的末尾释放,对吗?)。事实上,我们并没有像我们应该的那样为它们执行malloc(在作用域之后保存内存)。那么,当一个()完成时,内存堆栈不是向上移动了吗?它的光标和“world”将被放在内存中“hello”所在的位置?(看起来这里没有发生这种情况,我不明白为什么,

以下程序将按预期在屏幕“Hello\nWorld\n”('\n'=行向下)上打印。但事实上,正如我所了解到的,这里有些事情并没有按应有的方式去做。“hello”和“world”字符串是在函数中定义的(因此是本地的,它们的内存在函数作用域的末尾释放,对吗?)。事实上,我们并没有像我们应该的那样为它们执行malloc(在作用域之后保存内存)。那么,当一个()完成时,内存堆栈不是向上移动了吗?它的光标和“world”将被放在内存中“hello”所在的位置?(看起来这里没有发生这种情况,我不明白为什么,因此,如果内存块被保存并且没有在作用域之后返回,为什么我通常需要执行这个malloc?)

谢谢

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *a()
{
    char *str1 = "Hello";
    return str1;
}

char *b()
{
    char *str2 = "World";
    return str2;
}

int main()
{
    char *main_str1 = a();
    char *main_str2 = b();
    puts(main_str1);
    puts(main_str2);
    return 0;

}
#包括
#包括
#包括
char*a()
{
char*str1=“你好”;
返回str1;
}
char*b()
{
char*str2=“世界”;
返回str2;
}
int main()
{
char*main_str1=a();
char*main_str2=b();
puts(主存储器str1);
puts(主存储器2);
返回0;
}

编辑:所以你实际上是说,我的“hello”字符串在内存中占据恒定的位置,即使它在函数中,如果我有它的地址,我可以从任何我想要的地方读取它(因此它的定义就像malloc,但你不能释放它)-对吗?

堆栈上没有分配恒定字符串。堆栈上只分配了指针。从
a()
b()
返回的指针指向可执行内存的某个文本常量部分。

在本例中,由于字符串文本被分配到所有程序生存期内可用的内存数据中,所以所有字符串都有效。
您的代码相当于(我的意思是产生相同的结果):

这个代码不起作用

char* a()
{
  char array[6];
  strcpy(array,"Hello");
  return array;
}

因为
array[]
是在堆栈上创建的,当函数返回字符串文字(用
“引号”
定义的字符串)时,它会在编译时在程序的内存空间中静态创建并销毁。当您转到char*str1=“Hello”,您没有像调用malloc那样在运行时创建新内存。

C没有强制编译器按照OP的建议移动堆栈上的内存,这就是观察到的行为没有按预期失败的原因

编译器模型和优化可能允许一个程序,例如具有未定义行为(UB)的OP,显然可以在没有诸如内存损坏或seg故障等副作用的情况下工作。另一个编译器也可能编译相同的代码,但结果却截然不同

已分配内存的版本如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *a() {
  return strdup("Hello"); // combo strlen, malloc and memcpy
}

char *b() {
  return strdup("World");
}

int main() {
  char *main_str1 = a();
  char *main_str2 = b();
  puts(main_str1);
  puts(main_str2);
  free(main_str1);
  free(main_str2);
  return 0;
}
#包括
#包括
#包括
char*a(){
返回strdup(“Hello”);//组合strlen、malloc和memcpy
}
char*b(){
返回标准值(“世界”);
}
int main(){
char*main_str1=a();
char*main_str2=b();
puts(主存储器str1);
puts(主存储器2);
免费(主机str1);
免费(主服务器2);
返回0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char *a() {
  return strdup("Hello"); // combo strlen, malloc and memcpy
}

char *b() {
  return strdup("World");
}

int main() {
  char *main_str1 = a();
  char *main_str2 = b();
  puts(main_str1);
  puts(main_str2);
  free(main_str1);
  free(main_str2);
  return 0;
}