C 字符数组以何种方式在本地分配内存?

C 字符数组以何种方式在本地分配内存?,c,C,这是我写的代码 char *foo(); void main() { char *str=foo(); strcpy(str,"Holy sweet moses! I blew my stack!!"); printf("%s",str); } char * foo() { char str[256]; return str; } 当我在函数foo()中使用char数组时,m

这是我写的代码

    char *foo();

    void main()
    {
      char *str=foo();
      strcpy(str,"Holy sweet moses! I blew my stack!!");
      printf("%s",str);
    }

    char * foo()
    {
      char str[256];
      return str;
    }
当我在函数foo()中使用char数组时,main()函数中的strcpy不会将字符串复制到str中。但是,当我在函数foo()中使用int数组时,main()strcpy成功复制

i、 e

输出

   Holy sweet moses! I blew my stack!!
如果

输出:没有

你知道吗?如果您是,那么您确实知道您尝试执行的操作会调用。幸运的是,您的代码甚至打印出了一些内容,或者根本没有打印,而不是引用未分配的内存并由于堆损坏而崩溃

发件人::

堆栈/堆在多大程度上受操作系统或语言控制 运行时间

创建线程时,操作系统为每个系统级线程分配堆栈。通常,语言运行时会调用操作系统来为应用程序分配堆

它们的范围是什么

堆栈附加到线程,因此当线程退出时,堆栈被回收。堆通常在应用程序启动时由运行时分配,并在应用程序(技术上是进程)退出时回收

是什么决定了它们的大小

堆栈的大小是在创建线程时设置的。堆的大小是在应用程序启动时设置的,但可以随着空间的需要而增加(分配器从操作系统请求更多内存)。

您知道吗?如果您是,那么您确实知道您尝试执行的操作会调用。幸运的是,您的代码甚至打印出了一些内容,或者根本没有打印,而不是引用未分配的内存并由于堆损坏而崩溃

发件人::

堆栈/堆在多大程度上受操作系统或语言控制 运行时间

创建线程时,操作系统为每个系统级线程分配堆栈。通常,语言运行时会调用操作系统来为应用程序分配堆

它们的范围是什么

堆栈附加到线程,因此当线程退出时,堆栈被回收。堆通常在应用程序启动时由运行时分配,并在应用程序(技术上是进程)退出时回收

是什么决定了它们的大小


堆栈的大小是在创建线程时设置的。堆的大小在应用程序启动时设置,但可以随着空间的需要而增加(分配器从操作系统请求更多内存)。

当函数
foo()
返回时,它从堆栈返回字符串的地址。当函数退出时,指针是无用的,因为当foo()停止时,字符串将从堆栈中删除。因此,您有一个指向内存中某个位置的指针,但无法分辨其中的内容


阅读编译器警告,我打赌至少有一条告诉您,您的函数返回指向局部变量的指针。(我的函数返回,我也做了几次)。

当您的函数
foo()
返回时,它返回堆栈中字符串的地址。当函数退出时,指针是无用的,因为当foo()停止时,字符串将从堆栈中删除。因此,您有一个指向内存中某个位置的指针,但无法分辨其中的内容


阅读编译器警告,我敢打赌至少有一条告诉您,您的函数返回指向局部变量的指针。(我的函数返回指向局部变量的指针,我也这样做过几次)。

您所做的显然是未定义的,但是。。让我们试着理解为什么它与int而不是chars一起工作

TL;DR:printf使用堆栈,覆盖str指向的部分空间,但由于int数组在内存中比char数组大,因此它在堆栈中“遥遥领先”,不会被覆盖。

整数是4个字节,因此256个整数将是1024个字节

例如,如果数组在堆栈中,这将指向RBP-1024

对于字符,字符为1字节,256个字符为256字节

如果数组在堆栈中,例如,这将指向RBP-256

这是什么意思?当foo返回时,str指针将指向当前堆栈指针前面的1024或256字节

所以。。当你调用strcpy(str,“yourstring”);该内存可能会被strcpy和printf使用的堆栈覆盖。这里的问题是,它被覆盖,但不是所有堆栈,只是一点点,但足以覆盖256字节,因此,该函数可以覆盖复制的字符串,这不会发生在int数组中,因为字符串将被复制到堆栈指针前面1024位,strcpy和printf不会使用太多堆栈

让我向您展示堆栈将如何结束:

如果更改字符数组的大小,它可能会工作


所有这些都是未定义的行为,完全取决于您的体系结构、计算机和编译器。目前我正在使用Linux x86_64

你所做的显然是不确定的,但是。。让我们试着理解为什么它与int而不是chars一起工作

TL;DR:printf使用堆栈,覆盖str指向的部分空间,但由于int数组在内存中比char数组大,因此它在堆栈中“遥遥领先”,不会被覆盖。

整数是4个字节,因此256个整数将是1024个字节

例如,如果数组在堆栈中,这将指向RBP-1024

对于字符,字符为1字节,256个字符为256字节

如果数组在堆栈中,例如,这将指向RBP-256

这是什么意思?当foo返回时,str指针将指向当前堆栈指针前面的1024或256字节

所以。。当你调用strcpy(str,“yourstring”);该内存可能会被strcpy和printf使用的堆栈覆盖。这里的问题是,它被覆盖,但不是所有堆栈,只是一点点,但足以覆盖256字节,因此,该函数可以覆盖复制的字符串,这不会发生在int数组中,因为
   Holy sweet moses! I blew my stack!!
   char str[256]; //in foo()