如何C字符串在内存分配? [英] How C strings are allocated in memory?

查看:165
本文介绍了如何C字符串在内存分配?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

说我有一个简单的函数返回一个C字符串是这样的:

 为const char *的getString()
{
  为const char * PTR =等等等等;
  返回PTR;
}

和我打电话的getString()从main()中是这样的:


 为const char * S =的getString();


1)根据GDB,变量 PTR 被存储在堆栈上,但是的字符串被指出PTR 的是不是:

 (GDB)P和; PTR
$ 1 =(为const char **)0x7fffffffe688(GDB)p PTR
$ 2 = 0x4009fc等等等等

这是否意味着等等等等是不是里面的getString一个局部变量()?

我想,如果它是一个局部变量,我就无法将它传递给我的main()函数...
但是,如果它不是,它在哪里存放?在堆上?那是一个​​种的操作系统每次击中一个字符串,或什么时候实现动态内存分配?

2)如果我使用一个数组,而不是一个指针,这种方式:

 为const char * getString2()
{
  为const char a [] =等等等等等等;
  返回;
}

编译器警告我说:

警告:局部变量'A'返回的地址

(当然的程序编译,但它不工作)。

其实,如果我问gdb的,我得到

 (GDB)P和;一
$ 2 =(为const char(*)[15])0x7fffffffe690

不过,我认为,为const char * PTR 为const char a [] 基本上是同样的事情。看起来他们不是。

难道我错了吗? exactely两个版本之间的区别是什么?

感谢您!


解决方案

当你写

 为const char * PTR =等等等等;

则将发生以下情况:编译器生成一个常量字符串(类的char [] )的内容等等等等,并将其存储在某处的可执行文件的数据段(它基本上有一个类似的存储时间到变量使用静态关键字来声明)。

然后,将该字符串,它是地址的在整个程序的生命周期有效,的存储在 PTR 指针,这是然后返回。一切都很好。


  

这是否意味着等等等等不是里面的getString()?

局部变量

让我用蹩脚的英语句子来回应他们:是的,这不是

然而,当你声明一个数组,如

 为const char a [] =等等等等;

那么编译器不会产生一个静态的字符串。 (事实上​​,初始化字符串时,这是一个有些特殊情况。)然后,它会产生code,将分配给一个足够大的一块栈内存的 A 阵列(它不是一个指针!),将与字符串的字节填充它。在这里, A 实际上是一个局部变量并返回其地址会导致不确定的行为。

所以...


  

不过,我认为,为const char * PTR 为const char a [] 基本上是同样的事情。


没有,一点都没有,因为数组不是指针

Say I have a simple function that returns a C string this way:

const char * getString()
{
  const char * ptr = "blah blah";
  return ptr; 
}

and I call getString() from main() this way:

  const char * s = getString();

1) According to gdb, the variable ptr is stored on the stack, but the string pointed by ptr is not:

(gdb) p &ptr
$1 = (const char **) 0x7fffffffe688

(gdb) p ptr
$2 = 0x4009fc "blah blah"

Does this mean that "blah blah" is not a local variable inside getString()?

I guess that if it were a local variable, I would not be able to pass it to my main() function... But if it's not, where is it stored? On the heap? Is that a "kind of" dynamically memory allocation implemented by the OS every time it hits on a string, or what?

2) If I use an array instead of a pointer, this way:

const char *getString2()
{
  const char a[] = "blah blah blah";
  return a;
}

the compiler warns me that:

warning: address of local variable ‘a’ returned

(and of course the program compiles, but it doesn't work).

Actually, if I ask gdb, I get

(gdb) p &a
$2 = (const char (*)[15]) 0x7fffffffe690

But I thought that const char * ptr and const char a[] were basically the same thing. Looks like they're not.

Am I wrong? What is exactely the difference between the two versions?

Thank you!

解决方案

When you write

const char *ptr = "blah blah";

then the following happens: the compiler generates a constant string (of type char []) with the contents "blah blah" and stores it somewhere in the data segment of the executable (it basically has a similar storage duration to that of variables declared using the static keyword).

Then, the address of this string, which is valid throughout the lifetime of the program, is stored in the ptr pointer, which is then returned. All is fine.

Does this mean that "blah blah" is not a local variable inside getString()?

Let me respond with a broken English sentence: yes, it isn't.

However, when you declare an array, as in

const char a[] = "blah blah";

then the compiler doesn't generate a static string. (Indeed, this is a somewhat special case when initializing strings.) It then generates code that will allocate a big enough piece of stack memory for the a array (it's not a pointer!) and will fill it with the bytes of the string. Here a is actually a local variable and returning its address results in undefined behavior.

So...

But I thought that const char *ptr and const char a[] were basically the same thing.

No, not at all, because arrays are not pointers.

这篇关于如何C字符串在内存分配?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆