Geant4中报错:“segmentation fault :11”可能的原因
1.调用track->GetCreatorProcess()引起断错误
- 问题描述:
在Geant4的SteppingAction相关类中,想要获取当前产生当前粒子的物理过程用于后续计算,根据如下代码实现:
点击查看代码
G4Track* track = step->GetTrack();
//当前粒子是又哪个物理过程产生的。
const G4VProcess* creatorProcess = track->GetCreatorProcess();
G4String creatorProcessName = creatorProcess->GetProcessName();
报错“segmentation fault :11”,调试定位报错产生于该部分代码。
-
原因分析:
当粒子为初级粒子时,也就是parentID=0时,调用"track->GetCreatorProcess()"会出现"segmentation fault :11"的错误。
非法访问产生的原因就是当前粒子为初级粒子是源直接发射的粒子,并没有产生该粒子的物理过程,所以调用“track->GetCreatorProcess()”方法时会报错。 -
解决方案:
只要不是初级粒子,就可以访问产生该粒子的物理过程。建议解决方法,通过引入一个条件判断的方式,判断当前粒子是否为初级粒子,如果是则获取物理过程,不是则赋值其他:
点击查看代码
if(fTrack->GetParentID() != 0){
G4Track* track = step->GetTrack();
//当前粒子是又哪个物理过程产生的。
const G4VProcess* creatorProcess = track->GetCreatorProcess();
G4String creatorProcessName = creatorProcess->GetProcessName();
}else{
Do something
}
2.Geant4版本不同——在几何建模定义材料组成个数时引起段错误
- 问题描述:
运行某个Geant4项目时,本机运行报错(Geant4 10.7):“segmentation fault :11”。
但在服务器上能够正常运行,未报错(Geant4 10.6)。
在本机报错“segmentation fault :11”,调试定位报错产生于文件“DetectorConstruction.cc”中。

- 原因分析:
在“DetectorConstruction.cc”的文件方法Construct()中自定义材料时。根据根据质量分数建立建立材料时,如下方式。其中参数“nComponents”的意义为传入材料组成个数。
点击查看代码
G4Material(const G4String& name, //its name
G4double density, //density
G4int nComponents, //nbOfComponents
G4State state = kStateUndefined, //solid,gas
G4double temp = NTP_Temperature, //temperature
G4double pressure = CLHEP::STP_Pressure); //pressure
在编写代码时,将材料的组成写了N+1种,但实际只添加了N种元素,所以造成了报错。猜测可能原因版本更高的Geant4实现了代码检查,不允许材料的组成个数与实际添加个数不一致。所以在运行时会引起断错误。
- 解决方案:
将几何材料修改为正确的元素组成个数;
如下,nComponents在修改之前为9,和实际添加的元素个数不匹配(8种)。修改为正确的元素个数就成功了。

3.内存溢出-使用个人PC(虚拟机+Ubuntu)跑10W以上粒子 引起错误
- 问述题描:
使用个人PC(虚拟机+Ubuntu)跑10W以上粒子 - 错误截图:

- 原因分析:
个人PC有运行储存空间/时间限制 超过10W粒子就会自动停止运行 - 解决方案:
跑很多粒子的话,建议使用服务器进行多数粒子的模拟,个人pc仅适用于简单验证。
4.探测器名称-使用灵敏探测器,设置SD时名称不一致,引起错误
- 问题描述:
在使用SD时,设置的名称和实际填充的名称不一致 - 原因分析:
SD(Sensitive Detector)数据统计程序的统计名称不一致
或者说物理过程访问/存储的空间错误/不存在(这类问题都会导致)
在B1DetectorConstruction.cc中 定义SD
点击查看代码
void B1DetectorConstruction::ConstructSDandField() {
G4String SD_Name[1] = {"CrystalLV"};
for (int i = 0; i < 1; i++) {
auto absoSD = new G4MultiFunctionalDetector(SD_Name[i]);
G4SDManager::GetSDMpointer()->AddNewDetector(absoSD);
G4VPrimitiveScorer *primitive;
primitive = new G4PSEnergyDeposit("Edep");
absoSD->RegisterPrimitive(primitive);
SetSensitiveDetector(SD_Name[i], absoSD);
}
}
在想要统计的位置 填充SD的名字
点击查看代码
B1EventAction::B1EventAction()
: G4UserEventAction(),
fEdep(0.)
{
for(int i=0;i<1;i++)
fColID[i] = -1;
SD_Name[0] = "CrystalLV";
//SD_Name[1] = "logicdet2";
//SD_Name[2] = "logicdet3";
//SD_Name[3] = "logicdet4";
}
- 错误截图:

- 解决方案:
修改时需要仔细检查 错误提示在G4WT3/2 <CrystalLV/edep>
SD的名称一致即可
本文作者:阿比西尼亚喵
、绿巨鼠
文字编辑:Geant4Cat
本文链接:https://www.cnblogs.com/Geant4/articles/16445300.html
⛔转载请附上Geant4Cat的原文链接,并通过 E-mail 等方式告知,谢谢!否则举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?