-1

以下程序将按预期在屏幕上打印“Hello\nWorld\n”('\n' = line down)。但实际上,据我所知,这里的某些事情并没有按应有的方式完成。“hello”和“world”字符串是在函数内部定义的(因此是本地的,它们的内存在函数作用域的末尾被释放——对吧?)。实际上,我们并没有像我们应该做的那样为它们做 malloc(在作用域之后保存内存)。所以当 a() 完成时,内存堆栈不是向上移动它的光标和“世界”将被放置在“你好”所在的同一位置的内存中吗?(看起来它在这里没有发生,我不明白为什么,因此,如果实际上内存块被保存并且在作用域之后没有返回,为什么我通常需要做这个 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;

}

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

4

4 回答 4

0

常量字符串不在堆栈上分配。只有指针分配在堆栈上。从返回的指针a()b()指向可执行内存的某个字面常量部分。 处理这个话题的另一个问题

于 2013-08-09T21:07:08.907 回答
0

在这种情况下,一切正常,因为字符串文字分配在所有程序生命周期可用的内存数据中。
您的代码等效于(产生相同的结果,我的意思是):

char *a()
{
    return "Hello";
}

此代码不起作用

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

因为array[]在堆栈上创建并在函数返回时销毁

于 2013-08-09T21:07:16.190 回答
0

字符串文字(用 定义的字符串"quotes")在编译时在程序的内存空间中静态创建。当你去char *str1 = "Hello";的时候,你不会像malloc调用一样在运行时创建新的内存。

于 2013-08-09T21:08:52.913 回答
0

C 没有义务编译器按照 OP 的建议在堆栈上移动内存,这就是为什么观察到的行为没有像预期的那样失败。

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

分配内存的版本如下:

#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;
}
于 2013-08-09T22:35:47.557 回答