一道内存分配的面试题

这是读者在知识星球上写的面试题

我之前写的文章有很完整说过这部分

C语言,函数不可返回指向栈内存的指针

C 语言内存分配

堆和栈的区别(转过无数次的文章)

看完上面的文章,我觉得你至少对C语言程序变量内存有一个概念了解了。

然后看下这几张图

我们想知道一个程序栈的起始地址,我们只需要写个测试程序可以了。

#include "stdio.h"
#include "stdlib.h"int main(void)
{int a = 3;int *p = (int *)malloc(sizeof(int));printf("%p\n",&a);printf("%p\n",&p);printf("%p\n",p);return 0;
}

我们期望是这样的

实际运行是这样的,跟我们预期符合

0x7ffc3f47e1cc
0x7ffc3f47e1d0
0x562bf8677260

当然,也可以通过一些Linux 命令来查看这些信息

如果还有其他命令大家可以补充

size
nm
objdump

size 可以看到每个内存段的大小

weiqifa@bsp-ubuntu1804:~/c$ gcc neicunfenpei.c &&size ./a.outtext    data     bss     dec     hex filename1802     616       8    2426     97a ./a.out
weiqifa@bsp-ubuntu1804:~/c$

nm 可以看到更多的信息,包括里面的地址,还有标识符的区域,想看详细的可以看看man nm。

#include "stdio.h"
#include "stdlib.h"int gint = 1;int main(void)
{char * pch = "1231231";int a = 3;int *p = (int *)malloc(sizeof(int));printf("%p\n",&a);printf("%p\n",&p);printf("%p\n",p);return 0;
}

查看输出

weiqifa@bsp-ubuntu1804:~/c$ gcc neicunfenpei.c &&size ./a.outtext    data     bss     dec     hex filename1826     620       4    2450     992 ./a.out
weiqifa@bsp-ubuntu1804:~/c$ gcc neicunfenpei.c &&nm ./a.out
0000000000201014 B __bss_start
0000000000201014 b completed.7698w __cxa_finalize@@GLIBC_2.2.5
0000000000201000 D __data_start
0000000000201000 W data_start
0000000000000620 t deregister_tm_clones
00000000000006b0 t __do_global_dtors_aux
0000000000200db0 t __do_global_dtors_aux_fini_array_entry
0000000000201008 D __dso_handle
0000000000200db8 d _DYNAMIC
0000000000201014 D _edata
0000000000201018 B _end
0000000000000814 T _fini
00000000000006f0 t frame_dummy
0000000000200da8 t __frame_dummy_init_array_entry
0000000000000974 r __FRAME_END__
0000000000201010 D gint
0000000000200fa8 d _GLOBAL_OFFSET_TABLE_w __gmon_start__
0000000000000830 r __GNU_EH_FRAME_HDR
0000000000000580 T _init
0000000000200db0 t __init_array_end
0000000000200da8 t __init_array_start
0000000000000820 R _IO_stdin_usedw _ITM_deregisterTMCloneTablew _ITM_registerTMCloneTable
0000000000000810 T __libc_csu_fini
00000000000007a0 T __libc_csu_initU __libc_start_main@@GLIBC_2.2.5
00000000000006fa T mainU malloc@@GLIBC_2.2.5U printf@@GLIBC_2.2.5
0000000000000660 t register_tm_clonesU __stack_chk_fail@@GLIBC_2.4
00000000000005f0 T _start
0000000000201018 D __TMC_END__

ojbdump 大家可以自己去看看,参数比较多

来看看我们前面说的题目

#include "stdio.h"char * test_function(int n)
{int a = 3;char *p1 = "123";char p2[] = "456";printf("%p %p %p\n",&a,p1,p2);if(n == 0)return p1;return (char *)p2;
}int main(void)
{printf("%s\n",test_function(0));printf("%s\n",test_function(1));getchar();return 0;
}

这个代码在gcc下是编译会出现警告,而且运行后会出现段错误,因为我们访问了一个非法内存。

weiqifa@bsp-ubuntu1804:~/c$ gcc neicunfenpei.c && ./a.out
neicunfenpei.c: In function ‘test_function’:
neicunfenpei.c:11:12: warning: function returns address of local variable [-Wreturn-local-addr]return (char *)p2;^~~~~~~~~~
0x7fffe549a724 0x5641eaea1874 0x7fffe549a734
123
0x7fffe549a724 0x5641eaea1874 0x7fffe549a734
Segmentation fault (core dumped)
weiqifa@bsp-ubuntu1804:~/c$

你以为这就完了?

在devC++下,是可以正常运行的

这个dev C++ 让我觉得有点意思

所以在gcc 下,我们修改下代码

#include "stdio.h"char * pg =NULL;char * test_function(int n)
{int a = 3;char *p1 = "123";char p2[] = "456";pg = (char *)p2;printf("%p %p %p\n",&a,p1,p2);if(n == 0)return p1;return pg;
}int main(void)
{printf("%s\n",test_function(0));printf("%s\n",test_function(1));getchar();return 0;
}

再运行

没有段错误,但是第二次输出为空!

所以,你下次面试遇到,知道怎么回答了吗?

参考:

https://www.cnblogs.com/ittinybird/p/4657245.html


推荐阅读:

专辑|Linux文章汇总

专辑|程序人生

专辑|C语言

我的知识小密圈

关注公众号,后台回复「1024」获取学习资料网盘链接。

欢迎点赞,关注,转发,在看,您的每一次鼓励,我都将铭记于心~

嵌入式Linux

微信扫描二维码,关注我的公众号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

终于解决了

困扰很长事件的问题今天终于得到解决,或许是思维定式的原因,没有及时的绕过调整思路,也不知道今天晚上脑子这么开窍了,一下把问题给解决了,实在是开心啊改天还是把自己的成果贴出以示奖励自己的努力。转载于:https://w…

数据可视化插件

1、前端数据可视化插件:Highcharts、Echarts和D3 : https://blog.csdn.net/u013511989/article/details/72236788 (Echarts是canvas实现的,推荐) 2、Echarts学习:http://www.echartsjs.com/tutorial.html#5%20%E5%8…

一道内存分配的面试题后续

昨天写的题目,在VC6.0上面测试一下一道内存分配的面试题结果发现一个问题,发现输出结果竟然没有问题,我很慌,如果这样的输出结果没有问题的话,那肯定是跟我们的理论对不上号的。所以我只能继续调试先把问题抛在printf上…

每日一题(31)—— 全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么?

全局变量可不可以定义在可被多个.C文件包含的头文件中?为什么? 答:可以,在不同的C文件中以static形式来声明同名全局变量。 可以在不同的C文件中声明同名的全局变量,前提是其中只能有一个C文件中对此变量赋初值&#…

Qt学习之路(11): MainWindow

尽管Qt提供了很方便的快速开发工具QtDesigner用来拖放界面元素,但是现在我并不打算去介绍这个工具,原因之一在于我们的学习大体上是依靠手工编写代码,过早的接触设计工具并不能让我们对Qt的概念突飞猛进……前面说过,本教程很大程…

要毕业了,我应该做点啥?

这几天是高考的日子,高考结束,也意味着有很多人要离开学校,距离我毕业已经过去很多年了,现在还能记得那些无忧无虑的日子,毕竟人这一辈子,能这么肆无忌惮的时间并不多。最近因为发了几个不错的岗位招聘&…

每日一题(32)—— 联合体大小

设有以下说明和定义: typedef union {long i;int k[5];char c; } DATE; struct data {int cat;DATE cow;double dog; } too; DATE max;则语句 printf("%d",sizeof(struct date)sizeof(max));的执行结果是: 分析: 16位编译器中&…

开始→运行→输入的命令集锦

mstsc--远程桌面连接 logoff--注销命令 rononce -p --15秒关机 tsshutdn--60秒倒计时关机命令 iexpress--木马捆绑工具,系统自带 tourstart--xp简介(安装完成后出现的漫游xp程序) winchat--XP自带局域网聊天 sndrec32--录音机 Nsl…

我那个37岁的大神朋友,后续

还记得我之前写的这篇文章吗?我一个37岁的程序员朋友写这篇文章的时候,我建议我的这个朋友跳槽找更好的工作,可以换个行业,换一个更有钱的领域,做技术不能单单是做技术,需要有点眼光,比如选择行…

[洛谷P1231] 教辅的组成

题目大意:有n1本书,n2本练习册和n3个答案,然后又一些条件,说明某本答案可能和某本书对应,某本练习册可能和某本书对应,求最多有多少本完整的书(有书,练习册,答案&#xf…

每日一题(33)——用两个栈实现一个队列的功能?要求给出算法和思路

用两个栈实现一个队列的功能?要求给出算法和思路。 设2个栈为A,B, 一开始均为空. 入队: 将新元素push入栈A; 出队: (1)判断栈B是否为空; (2)如果不为空,则将栈B中最顶元素pop出;如果为空,则将A中所有元素POP出并…

可以用在任何人身上:百战百胜人生10大成功秘诀

这里介绍的10个成功秘诀,可以接受时代变迁的考验,可以用在任何人身上,更可以与时推移,永不落伍。尽管它们不是立杆见影的妙药,但只要你身体力行,定能改善你的生活方式。  1.必须先在内心深处感受到爱&…

扒一扒中断为什么不能调printf

[导读] 大家好,我是逸珺。前面说会写一下Modbus-RTU的实现,写了1000多字了,有兴趣的稍等一下哈。前面在一个群里看到一个朋友在一个串口接收中断里打印遇到了问题,今天聊下这个话题。扒一扒printf 对于单片机中printf到底向哪里打…

P4555 最长双回文串

题目描述 顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为abc,逆序为cba,不相同)。 输入长度为 n的串 S ,求 S的最长双回文子串 T ,即可将 T 分为两部分 X, …

每日一题(34)—— 线程

1.线程的概念: 2 与进程的区别: 3 线程与进程的区别和联系? 线程是否具有相同的堆栈? 1、线程是指进程内的一个执行单元,也是进程内的可调度实体. 2、与进程的区别: (1)调度:线程作为调度和分配的基本单位,进程作为拥有资源…

如何利用MySQL加密函数保护Web网站敏感数据

如果您正在运行使用MySQL的Web应用程序,那么它把密码或者其他敏感信息保存在应用程序里的机会就很大。保护这些数据免受***或者窥探者的获取是一个令人关注的重要问题,因为您既不能让未经授权的人员使用或者破坏应用程序,同时还要保证您的竞争…

躺平,躺下就能赢吗?

之前在群里讨论这个话题,说躺平挺好的,没那么大压力,我也觉得躺平是好事,每个人都要追求理想的权力,那么反过来,每个人也有不追求理想的权力。躺平如果说的好听一些,也可以认为是躺赢&#xff0…

第一站---大连---看海之旅

5月下旬至7月上旬 是大连最舒服的季节 还不是很热 微风拂面 神清气爽的感觉 工具/原料 坐公交的零钱防晒霜可以下水的鞋推荐一下旅游路线吧个人意见:来大连必去的几个景点分为两类:免费的: 1.星海湾景区。在星海湾景区你可以来到星海广场、星海湾浴场、星海公园,这…

感觉stm32太简单是一种自负吗?

其实简单或者复杂都不重要,重要的是通过STM32我们能学习到什么?做一个键盘/鼠标,可以学习USB协议。做一个联网设备,需要学习以太网,TCP/IP协议的底层实现。做一个无线设备,可能需要学习蓝牙、WIFI或者zigbe…

回车 触发 提交事件

//gridview 文本框 回车 触发 Button 事件 < script type "text/javascript" language "javascript" > function clickButton() { if ( event.keyCode 13 ) { document.all ( ibtnUpdate ).click(); return false; } } < / script > < a…