我必须在函数内malloc返回一个字符串吗?

时间:2013-08-09 21:00:51

标签: c malloc

以下程序将按照预期在“Hello \ nWorld \ n”('\ n'= line down)屏幕上打印。但事实上,正如我所知,这里的某些事情并没有按照预期进行。 “hello”和“world”字符串是在函数内部定义的(因此是本地的,它们的内存在函数范围的末尾发布 - 对吗?)。实际上我们没有像我们应该那样为它们做一个malloc(为了在范围之后保存内存)。所以当a()完成时,是不是内存堆栈向上移动它的光标,“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;

}

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

4 个答案:

答案 0 :(得分:0)

不在堆栈上分配常量字符串。只在堆栈上分配指针。从a()b()返回的指针指向可执行内存的某些字面常量部分。 Another question dealing with this topic

答案 1 :(得分:0)

在这种情况下,所有工作都可以,因为字符串文字是在可用于所有程序生命周期的内存数据中分配的 你的代码相当于(产生相同的结果,我的意思):

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

此代码不起作用

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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;
}