一道内存分配的面试题

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

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

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,一经查实,立即删除!

相关文章

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

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

Qt学习之路(11): MainWindow

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

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

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

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

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

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

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

躺平,躺下就能赢吗?

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

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

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

耗时两年,19岁小伙采用230片纯74逻辑芯片搭建出32位处理器!可玩贪吃蛇

从设计 CPU、制作原型机、最终成品到软件编程,19 岁极客小伙用了整整两年的时间。RISC-V 是一个基于精简指令集(RISC)原则的开源指令集架构(ISA),它是对应开源软件运动的一种「开源硬件」。该项目于 2010 年…

VC++ 6.0 与VS2008 C++ DEBUG工具(Windows)介绍

在VC 6.0 里面,debug工具有这些: 请看大图展示: 这里面几个工具都是经常用到的。比如:上下文信息,可以查看当前变量的值和地址Memory: 可以输入地址查看里面的内容。对调试和检查指针特别有用。 在vs2008里…

数组与指针不能混用的情况

扫描二维码获取更多精彩嵌入式杂牌军编辑|追梦星空公众号|嵌入式杂牌军✎ 编 者 悟 语正当性的出发点应该是少目的性、不带偏见、以尊重为前提的多方考虑。文 章 导 读C中的数组有能混用的情况,有不能混用的情况,今天就带小伙伴们探究一下!阅…

[CTO札记]盛大游戏上市,是对《文化产业振兴规划》的响应

重要国策《文化产业振兴规划》于9月26日正式对外公布。巧合的是,就在前一天(9月25日 ),盛大游戏(SDG)成功在NASDAQ上市,并且创下了美股IPO规模之最(10亿美元)。1&#xf…

Linux内核入门之路 (非广告)

笔者从开始接触 Linux 内核应该有 4 ~ 5 年了,虽然不敢说非常了解 Linux 内核,但起码也有了点眉目。所以,本文主要想分享一下我的 Linux 内核入门之路,如果对大家有帮助的话,希望能够转发一下,帮助更多想学…

万能红外遥控开发

下班刚回到家,天气很热~空调遥控器呢?找不到!躺平不想动~风扇遥控器呢?找不到!想看电视,不想动~电视遥控器呢?找不到!好不容易找到了,遥控器没电?崩溃&#x…

[Lydsy1805月赛] 对称数

挺不错的一道数据结构题QWQ。 一开始发现这个题如果不看数据范围的话,妥妥的树上莫队啊23333,然鹅10组数据是不可能让你舒舒服服的树上莫队卡过的23333 于是想了想,这个题的模型就是,把u到v链上的权值出现奇偶次的01串搞出来&…

linux下被遗忘的gpio_keys按键驱动

我们新项目硬件设计上使用gpio口做按键,所以我就需要搞定这个驱动,本来想自己写一个gpio口的按键驱动,然后看了下内核下面的代码,已经有现成的了。Linux内核下游很多很多的现成驱动,只要你想得到的,基本都是…

如何通过审计安全事件日志检测密码喷洒(Password Spraying)攻击

许多渗透测试人员和攻击者通常都会使用一种被称为“密码喷洒(Password Spraying)”的技术来进行测试和攻击。对密码进行喷洒式的攻击,这个叫法很形象,因为它属于自动化密码猜测的一种。这种针对所有用户的自动密码猜测通常是为了避…

单片机编程技巧—状态机编程

摘要:不知道大家有没有这样一种感觉,就是感觉自己玩单片机还可以,各个功能模块也都会驱动,但是如果让你完整的写一套代码,却无逻辑与框架可言,上来就是开始写!东抄抄写抄抄。说明编程还处于比较…

啥叫旁路电容?啥叫去耦?可以不再争论了吗

1. 旁路和去耦先谈两个比较重要的概念:旁路电容(Bypass Capacitor),去耦电容(Decoupling Capacitor)。只要是设计过硬件电路的同学肯定对这两个词不陌生,但真正理解这两个概念的可能并不多。我刚毕业时就问过我的师傅,为什么总是在…

H5活动产品设计指南基础版

本文来自 网易云社区 。 H5一般页面不会很多,看似简单,实际上会有很多细节需要注意,我自己在做过了几个H5之后,发现了一些常犯的问题,做了小结,希望给新开始做H5的产品相关的同学提供一些帮助。 首先说说一…

图解丨在嵌入式设备上实现HTTP服务器

您好呀,我是小二。本期为大家带来一个 WiFi 应用的实际场景,其实在之前「我对 WiFi 驱动移植过程,做了一次总结复盘」这篇文章中有简单提过,但由于内容较多,就单独摘出来了。来自读者的催更????????????&a…