问个C++和linux内核的相关问题,挺奇怪的

sopro 2006-12-15 06:39:05
我写了程序,如下:
#include <iostream>
using namespace std;

char* func()
{
char cArray[] = "123456";
return cArray;
}

int main()
{
char* p = func();
cout << hex << reinterpret_cast<int>(p) << endl; //以16进制输出p的地址
}

结果:
bf8bcc41 (每次结果不一样)
bff442c1
...
(或者其他数值)

我觉的很奇怪!
我们暂且不论我返回的是一个局部数组的首地址(我知道这是绝对应该避免的),就现在出现的问题,我感到困惑。

一个进程再虚拟地址空间的分布我大概是了解的。在kernel下面,也就是0xc000000地址之下应该是进程的stack(根据函数调用的情况动态变化)。那么,认为,既然是相同的程序运行,进程在虚拟地址空间中的分布应该是一摸一样的,局部数组的首地址那么也应该是同一个虚拟地址(当然,物理地址很可能不一样,但是进程看到的应该只能是虚拟地址)

今天和其他人讨论了半天,没弄明白,特地注册了一个帐号到csdn上面请高手做答,谢谢!
...全文
1844 25 打赏 收藏 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengfeiwuwq 2006-12-21
  • 打赏
  • 举报
回复
的确值得学习
lurenfu 2006-12-20
  • 打赏
  • 举报
回复
看看Security Enhanced Linux,有讲SE-Linux是如何防止缓冲区溢出攻击的,其中提到一点就是运行的起始地址还有栈地址在每次运行时是不同的,在以前的2.4内核中,同一个程序每次运行时的虚拟地址空间布局是一样的,2.6的内核作了改进
playmud 2006-12-20
  • 打赏
  • 举报
回复
线形地址,不是物理地址.
WaterWalker 2006-12-20
  • 打赏
  • 举报
回复
哪里有介绍捏?好象windows中的地址都不是物理地址吧???
windows也不让你操作物理地址吧,因为windows出来时候,就说访问物理地址是没有意义,
因为本身进程物理地址就可变,可搬移。你们说的windows地址实际上只是相对地址吧?

再研究研究。。。
---------------------------
物理地址可变化是为了虚拟内存的需要.这个操作系统基本都实现了.
逻辑地址可变化,这个在windows还没实现.
楼主的问题属于逻辑地址的问题.
test2002 2006-12-20
  • 打赏
  • 举报
回复
楼上你错了,这个不是linux的缺陷,而是新版本的linux做的一个改进。
windows实际上还没有这样,至少xp 不是,据微软的最新消息他们新版本的windows加入了这个功能,当然也不是特别新的消息。

------------------------------------------------------
哪里有介绍捏?好象windows中的地址都不是物理地址吧???
windows也不让你操作物理地址吧,因为windows出来时候,就说访问物理地址是没有意义,
因为本身进程物理地址就可变,可搬移。你们说的windows地址实际上只是相对地址吧?

再研究研究。。。
wd_6532 2006-12-20
  • 打赏
  • 举报
回复
那么,认为,既然是相同的程序运行,进程在虚拟地址空间中的分布应该是一摸一样的,局部数组的首地址那么也应该是同一个虚拟地址
==============
没有人保证这个。
sopro 2006-12-19
  • 打赏
  • 举报
回复
to: test2002(test2002)

http://community.csdn.net/Expert/topic/5235/5235454.xml?temp=.4043238
最后的几个回复(关于Address Space Layout Randomization),那个才是我要的答案

建议你先弄清楚进程的address space layout再说
test2002 2006-12-19
  • 打赏
  • 举报
回复
一个进程再虚拟地址空间的分布我大概是了解的。在kernel下面,也就是0xc000000地址之下应该是进程的stack(根据函数调用的情况动态变化)。那么,认为,既然是相同的程序运行,进程在虚拟地址空间中的分布应该是一摸一样的,局部数组的首地址那么也应该是同一个虚拟地址(当然,物理地址很可能不一样,但是进程看到的应该只能是虚拟地址)

----------------------------------------------------------------
你要看为什么栈地址改变,看你的程序,只输出一次,你肯定在不同的进程中比较了,当然地址不同是正常的。

你在同一个进程中比较 看看,程序修改如下:

int main()
{
char* p;
for(int i=0;i<10;i++)
{
p = func();
cout << hex << reinterpret_cast<int>(p) << endl; //以16进制输出p的地址
}
}

看看每次输出是否一致!!!
test2002 2006-12-19
  • 打赏
  • 举报
回复
靠,都没说到点子上

char* func()
{
char cArray[] = "123456";
return cArray;
}

-----------------------
cArray这个字符数组,是局部变量。

每次程序运行的时候,局部变量由于分配在栈上的,而这个栈是动态改变的,应此,栈地址是动态改变的,当然每次运行分配的地址是不一样的阿,所以楼主每次输出的这个地址(野地址)是不一样的,有什么奇怪的!!!
playmud 2006-12-19
  • 打赏
  • 举报
回复
楼上你错了,这个不是linux的缺陷,而是新版本的linux做的一个改进。
windows实际上还没有这样,至少xp 不是,据微软的最新消息他们新版本的windows加入了这个功能,当然也不是特别新的消息。
test2002 2006-12-19
  • 打赏
  • 举报
回复
这句话本身没错,不过,从你回帖的上下文以及你举的例子来看,你理解错了。根据网友给出的解释,2.4内核之前如果运行这个程序,每次返回的地址是一样的。2.6内核之后,返回的地址不一样,你知道是什么原因么?
根据其他网友的解释,2.4内核中,对每个进程来说,不管这个进程运行了多少次,在地址空间的布局都是一样的,因此返回的地址是一样的。很明显(我以为),你认为就算是同一个进程,只要是不同的运行,在栈中的内存布局是不一样的。
现在返回的地址不一样的原因是安全性考虑的原因,而不是你当初理解的理由。
你这样算不算是错误的理解凑巧导致了正确的答案?

--------------------------------------------------------------
是的,linux以前版本的缺陷。
实际上编译原理已经解释得很清楚了,就是进程运行空间,时间的不可逆性。也就是说相同的程序,运行的轨迹不可重复性,当然包括运行空间的不可逆性了。

实际上windows也是一直这样的,他的物理地址也是变化的,如果是没有变化,只是逻辑上没有变化而已,而且windows进程是可重定位的,不确定的,可由操作系统随时搬移的。
sopro 2006-12-19
  • 打赏
  • 举报
回复
--------------
实际上地址改变,还是因为不同的进程的运行造成的,难道我说错了吗??
--------------
这句话本身没错,不过,从你回帖的上下文以及你举的例子来看,你理解错了。根据网友给出的解释,2.4内核之前如果运行这个程序,每次返回的地址是一样的。2.6内核之后,返回的地址不一样,你知道是什么原因么?
根据其他网友的解释,2.4内核中,对每个进程来说,不管这个进程运行了多少次,在地址空间的布局都是一样的,因此返回的地址是一样的。很明显(我以为),你认为就算是同一个进程,只要是不同的运行,在栈中的内存布局是不一样的。
现在返回的地址不一样的原因是安全性考虑的原因,而不是你当初理解的理由。
你这样算不算是错误的理解凑巧导致了正确的答案?


如果我误解了你,向你道歉。回帖的时候态度确实恶劣了点,sorry,sorry
大家共同进步吧,都是为了学习
test2002 2006-12-19
  • 打赏
  • 举报
回复
地址每次都在变化才是正常的,因为最新的linux发行版中加了入防止缓冲区溢出的诸多措施,运行时的启动地址是变化的,这样就可以避免猜测缓冲区溢出地址的可能,还有其它几种方法,如设置stack区和data区不可执行等,具体可以参考secure enhanced linux

------------------------------------
实际上地址改变,还是因为不同的进程的运行造成的,难道我说错了吗??

不要一来就说 “建议你先弄清楚进程的address space layout再说”,

我说的不同进程是同样程序运行多次(你这例子不是关了程序,然后再运行比较地址的吗?)

你在一个程序中调用10次,看看地址改了没有??

没搞懂别人什么意思就...





playmud 2006-12-19
  • 打赏
  • 举报
回复
原来如此,我说怎么2.4内核没这种情况呢,原来为了安全作了一些改动.
长知识了.
TinyAnt 2006-12-18
  • 打赏
  • 举报
回复
你在什么系统下运行这程序?有没有调试工具,跟踪下char* func()应该可以得出答案。
TinyAnt 2006-12-18
  • 打赏
  • 举报
回复
楼主知道cArray是野指针啦,只是想知道为什么cArray返回随机值
xiaodong_ustb 2006-12-18
  • 打赏
  • 举报
回复
char* func()
{
char cArray[] = "123456";
return cArray;
}
野指针呀,局部变量是在栈内分配内存空间,当程序从func函数退出时,系统回收该内存空间,所有你返回的指针所指向的空间系统可以分配给其它函数使用,所以你打印出的东西每次都不一样,这是很危险的,如果那个地方正好放着你的100万银行账户,你给它改成0,嘿嘿.....
playmud 2006-12-18
  • 打赏
  • 举报
回复
//test.c
#include <stdio.h>
void func()
{
int i=10;
printf("%x\n",&i);
}
int main()
{
func();
return 0;
}
playmud 2006-12-18
  • 打赏
  • 举报
回复
2.6内核对进城的进城空间布局变化不小,2.4内核不会出现这种情况。
应该和操作系统的进程调用相关
Andrionda 2006-12-18
  • 打赏
  • 举报
回复
return cArray; 程序有错误!
char cArray[] = "123456"; 是存在于函数得临时栈区,函数反馈回来得时候,该存储区已经释放掉了,return反馈回来得东东很随机得!
加载更多回复(5)
内容概要:本文针对质子交换膜燃料电池(PEMFC)在动态压力工况下的最大功率点跟踪(MPPT)问题,提出了一种压力工况协同调控下的自适应高阶滑模控制策略,并基于Simulink平台完成了系统建模与仿真实现。该策略融合高阶滑模控制的强鲁棒性与自适应机制的参数在线优化能力,有效克服了PEMFC系统固有的非线性、外部扰动及工况时变性等挑战,实现了对最大功率点的快速、精确与稳定跟踪。研究内容涵盖控制策略的理论设计、李雅普诺夫稳定性分析、自适应律构建以及在多种动态工况下的仿真实验验证,结果表明该方法相较于传统控制策略具有更快的动态响应速度、更小的稳态振荡以及更强的抗干扰能力,显著提升了PEMFC系统的能量转换效率与运行稳定性。; 适合人群:具备一定控制理论基础和Simulink仿真经验,从事新能源发电系统、燃料电池控制、电力电子变换或先进控制算法研究的研发人员及高校研究生。; 使用场景及目标:①应用于燃料电池发电系统的高性能最大功率点跟踪控制设计;②为解决强非线性、多扰动耦合的能源系统提供先进的自适应鲁棒控制方案;③通过Simulink仿真验证高阶滑模与自适应控制算法的有效性,服务于科研项目攻关或工程原型开发。; 阅读建议:建议读者结合Simulink模型同步学习,重点关注控制律设计原理、自适应机制实现方式及仿真结果对比分析部分,并可通过与传统滑模控制进行对比,深入理解该策略在鲁棒性与动态性能上的优越性。
下拉可见数据集可视化效果示意。 【数据集概况】 · 检测类别(中文):[滴落物(Drop)] · 训练集:2021 张 · 验证集:128 张 · 测试集:42 张 · 总计:2191 张 该数据集聚焦于工业生产环境中地面或设备表面出现的各类滴落物检测,通过多角度、多光照条件下的图像采集,全面覆盖了不同形态、颜色和材质的滴落物样本。数据集真实还原了车间地面、金属板、木质结构等复杂背景下的实际场景,为自动化巡检系统提供了高价值的视觉依据,有助于实现对潜在污染源或泄漏点的早期识别与预警。... 【训练曲线与评估图】 【模型训练配置】 参数 | 值 模型 | yolo26n 训练轮数 | 100 epochs 输入尺寸 | 640x640 批次大小 | 24 优化器 | auto 初始学习率 | 0.01 训练设备 【关键指标汇总】 训练了 71 个 epoch,最终轮指标: 指标 | 数值 mAP50 | **0.8949** mAP50-95 | 0.5139 Precision | 0.8991 Recall | 0.8527 train/box_loss | 0.8544 train/cls_loss | 0.4842 val/box_loss | 1.5612 val/cls_loss | 0.6862 【训练过程分析】 71 轮训练后 mAP50 为 0.8949,模型基本收敛但还有提升余地。Loss 曲线下降正常,后期趋于平缓。mAP50-95 为 0.5139,和 mAP50 差距 0.38,定位精度是主要短板。 【模型性能评估】 Precision 0.8991、Recall 0.8527,精度高于召回,存在一定漏检。 【预测效果展示】 验证集预测效果较好,检测框基本准确覆盖滴落物,置信度整体偏高。 【改进建议】 1. 增强难例挖掘:在大规模数据中筛选误检...
【2026年华为杯D题】山区洪涝灾害下无人机运输与通信协同优化(思路、代码、论文,持续更新)内容概要:本文围绕山区洪涝灾害背景下无人机在运输与通信任务中的协同优化问题展开研究,旨在通过数学建模与算法设计解决复杂地理环境下的应急响应难题。文中提出了综合考虑无人机飞行路径规划、物资投送效率、通信中继覆盖能力及多机协同控制的优化模型,并结合智能优化算法(如灰狼优化算法、鲸鱼算法等)进行求解,确保在灾情紧急、基础设施受损的情况下实现高效、可靠的救援支持。研究涵盖了从任务建模、约束条件设定到多目标优化框架构建的全过程,强调了算法在实际场景中的鲁棒性与适应性。; 适合人群:具备一定编程基础和运筹优化知识,从事应急管理、无人机应用或智能算法研究的研发人员及高校研究生。; 使用场景及目标:①应对山区洪涝等自然灾害时的无人机应急物流与通信保障;②提升多无人机系统在复杂环境下的协同作业能力,优化路径规划与资源分配策略;③为相关科研项目提供可复现的算法模型与仿真代码参考。; 阅读建议:建议结合文中提供的Matlab代码进行实践操作,重点关注多目标优化模型的构建逻辑与智能算法的实现细节,同时可参照其他类似无人机路径规划案例加深理解,以实现理论与应用的有效结合。

23,224

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧