c++ - EXC_BAD_ACCESS:使用 std::array 的问题
问题描述
我正在尝试将 boost 库的 odeint 与std::vector
or一起使用std::array
。在这两种情况下我都没有编译问题,但是,在std::array
. 下面给出的是 MWE。
我在头文件中定义了两个类:ODE1
和ODE2
with std::vector
, 和。std::array
ode.hpp
#ifndef ODE_HPP_
#define ODE_HPP_
// c++ standard library headers
#include <array>
#include <iostream>
#include <vector>
namespace ode {
constexpr size_t n_variables = 1e4;
} // namespace ode
class ODE1 {
public:
ODE1(const double o) : V_(ode::n_variables, o) {} // explicit constructor
std::vector<double>& GetVoltage() { return V_; }
void operator()(const std::vector<double>& Y, std::vector<double>& dYdt,
const double /* time */) {
using namespace ode;
for (size_t n = 0; n < n_variables; n++) dYdt[n] = Y[n];
}
private:
std::vector<double> V_{};
};
class ODE2 {
using Array = std::array<double, ode::n_variables>;
public:
// constructors
ODE2(const double o) { V_.fill(o); } // explicit constructor
Array& GetVoltage() { return V_; }
void operator()(const Array& Y, Array& dYdt, const double /* time */) {
using namespace ode;
for (size_t n = 0; n < n_variables; n++) dYdt[n] = Y[n];
}
private:
Array V_{};
};
#endif // ODE_HPP_
主要功能定义在文件“ode.cpp”中
// related header
#include "ode.hpp"
// other library headers
#include <boost/numeric/odeint.hpp>
int main() {
constexpr double abs_err = 1.0e-10;
constexpr double rel_err = 1.0e-8;
constexpr double sim_duration = 20.0; // ms
constexpr double t_start = 0; // ms
constexpr double t_stop = t_start + sim_duration; // ms
constexpr double dt = 5e-3; // ms
{
std::cout << "ODE1\n";
using namespace boost::numeric::odeint;
using error_stepper_type = runge_kutta_dopri5<std::vector<double>>;
ODE1 o(-60.0);
integrate_adaptive(make_controlled<error_stepper_type>(abs_err, rel_err), o,
o.GetVoltage(), t_start, t_stop, dt);
}
{
std::cout << "ODE2\n";
using namespace boost::numeric::odeint;
using error_stepper_type =
runge_kutta_dopri5<std::array<double, ode::n_variables>>;
ODE2 o(-60.0);
integrate_adaptive(make_controlled<error_stepper_type>(abs_err, rel_err), o,
o.GetVoltage(), t_start, t_stop, dt);
}
return 0;
}
我在 macOS Big Sur (11.5.2) 上使用 clang 编译器编译如下
c++ -O0 -g -fsanitize=address -fno-omit-frame-pointer -Wall -Wextra -Wpedantic -std=c++17 ode.cpp -o ode
正如我上面提到的,我没有遇到编译问题。当我运行可执行文件时,我遇到以下问题
ODE1
ODE2
AddressSanitizer:DEADLYSIGNAL
=================================================================
==30573==ERROR: AddressSanitizer: stack-overflow on address 0x7ffee6a1e3f8 (pc 0x00010896439e bp 0x7ffee6d18610 sp 0x7ffee6a1e400 T0)
#0 0x10896439e in unsigned long boost::numeric::odeint::integrate_adaptive<boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_dopri5<std::__1::array<double, 10000ul>, double, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_fsal_tag>, ODE2, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::null_observer>(boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_dopri5<std::__1::array<double, 10000ul>, double, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_fsal_tag>, ODE2, std::__1::array<double, 10000ul>&, double, double, double, boost::numeric::odeint::null_observer) integrate_adaptive.hpp:40
#1 0x10894335e in unsigned long boost::numeric::odeint::integrate_adaptive<boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_dopri5<std::__1::array<double, 10000ul>, double, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_fsal_tag>, ODE2, std::__1::array<double, 10000ul>, double>(boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_dopri5<std::__1::array<double, 10000ul>, double, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_fsal_tag>, ODE2, std::__1::array<double, 10000ul>&, double, double, double) integrate_adaptive.hpp:83
#2 0x10894262c in main ode.cpp:30
#3 0x7fff203d0f3c in start+0x0 (libdyld.dylib:x86_64+0x15f3c)
SUMMARY: AddressSanitizer: stack-overflow integrate_adaptive.hpp:40 in unsigned long boost::numeric::odeint::integrate_adaptive<boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_dopri5<std::__1::array<double, 10000ul>, double, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations, boost::numeric::odeint::initially_resizer>, boost::numeric::odeint::default_error_checker<double, boost::numeric::odeint::array_algebra, boost::numeric::odeint::default_operations>, boost::numeric::odeint::default_step_adjuster<double, double>, boost::numeric::odeint::initially_resizer, boost::numeric::odeint::explicit_error_stepper_fsal_tag>, ODE2, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::null_observer>(boost::numeric::odeint::controlled_runge_kutta<boost::numeric::odeint::runge_kutta_dopri5<std::__1::array<double, 10000ul>, double, std::__1::array<double, 10000ul>, double, boost::numeric::odeint::array_a
==30573==ABORTING
zsh: abort ./ode
n_variables
奇怪的是,当我将标头中的参数 , 从 10000 更改为 1000时,我没有遇到问题。
此外,我曾经lldb
调试过这个问题,它似乎是stop reason = EXC_BAD_ACCESS (code=2, address=0x7ffeef3fbc58)
我不太确定这里的问题是什么!任何帮助将不胜感激。
解决方案
ASAN 增加了程序所需的堆栈内存量,而您的程序已经需要很多。增加堆栈大小限制:
$ ulimit -s 81920
$ ./ode
ODE1
ODE2
$
推荐阅读
- php - 在浏览器中执行的 PHP Bash 脚本
- php - Mysql 请求返回 null Controller PHP
- c++ - 简单数据类型中的模板类型推导
- java - 在android中编写单元时如何检查视图寻呼机是否位于最后一个元素
- firebase - Firebase - 自定义网址 - 避免 *.firebaseio.com
- python - 如果我在 macOS 上通过 launchctl 启动守护程序,Pynput 将无法工作
- flutter - Boxshadow 出现在其他小部件的后面
- python - 使用python使用tcp套接字从文件中读取和删除瞬时数据
- sql - WHERE 语句选择记录前一天,但当当天是星期一时选择星期五记录 Microsoft SQL
- c - 使用 AVX 内在函数对 __m512i 中的 8 位整数求和