в начале моего файла объявлена константа: static c...
बनाया गया: 2 अप्रैल 2026
का उपयोग करके उत्तर दिया गया GPT-5.4 Thinking द्वारा Chat01
बनाया गया: 2 अप्रैल 2026
का उपयोग करके उत्तर दिया गया GPT-5.4 Thinking द्वारा Chat01
в начале моего файла объявлена константа: static constexpr int AGP_MAX_FULL_DIM = 16; затем у меня есть блок генерации сидов и я подозреваю что где-то там есть ошибка выхода за пределы массива, чтения за пределы или записи за пределы, точно что-то не так с памятью так как получаю стабильно код ошибки: "Необработанное исключение:
Необработанное исключение:
Необработанное исключение:
Необработанное исключение:
Необработанное исключение:
Необработанное исключение:
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в TESTAGP.MyForm.RunAgpCppAtPoint(Single tx, Single ty) в E:\TEST_AGP\MyForm.h:строка 1036
в TESTAGP.MyForm.SolvePoseByBackend(Single tx, Single ty) в E:\TEST_AGP\MyForm.h:строка 1321
в TESTAGP.MyForm.RunPositioningMode() в E:\TEST_AGP\MyForm.h:строка 1879
в TESTAGP.MyForm.OnOptimizeClick(Object sender, EventArgs e) в E:\TEST_AGP\MyForm.h:строка 2185
в System.Windows.Forms.Control.OnClick(EventArgs e)
в System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
в System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
в System.Windows.Forms.Control.WndProc(Message& m)
в System.Windows.Forms.ButtonBase.WndProc(Message& m)
в System.Windows.Forms.Button.WndProc(Message& m)
в System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
в System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
в System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
в System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
в System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
в main() в E:\TEST_AGP\MyForm.cpp:строка 20
в mainCRTStartup()
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в main() в E:\TEST_AGP\MyForm.cpp:строка 23
в mainCRTStartup()
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в main() в E:\TEST_AGP\MyForm.cpp:строка 23
в mainCRTStartup()
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в main() в E:\TEST_AGP\MyForm.cpp:строка 23
в mainCRTStartup()
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в main() в E:\TEST_AGP\MyForm.cpp:строка 23
в mainCRTStartup()
System.AccessViolationException: Попытка чтения или записи в защищенную память. Это часто свидетельствует о том, что другая память повреждена.
в main() в E:\TEST_AGP\MyForm.cpp:строка 23
в mainCRTStartup()
job aborted:
[ranks] message
[0-2] terminated
[3] process exited without calling finalize
[4-5] terminated
---- error analysis -----
[3] on DESKTOP-C1VT6JF
E:\TEST_AGP\x64\Release\TEST_AGP.exe ended prematurely and may have crashed. exit code 0xc0000005", сам блок генерации сидов: "static constexpr int AGP_MAX_SEED_STRIDE = 64, AGP_MAX_GENERATED_SEEDS = 1024, AGP_SOBOL_BASE_DIMS = AGP_MAX_FULL_DIM;
static __declspec(noalias)__forceinline unsigned agp_splitmix32(unsigned x)noexcept { x += 0x9E3779B9u; x = (x ^ (x >> 16)) * 0x85EBCA6Bu; x = (x ^ (x >> 13)) * 0xC2B2AE35u; return x ^ (x >> 16); }
static __declspec(noalias)__forceinline float agp_radical_inverse_scrambled(unsigned long long index, unsigned base, unsigned scramble)noexcept { unsigned long long base64 = static_cast<unsigned long long>(base); float inv_base = 1.0f / static_cast<float>(base), inv_pow = inv_base, value = 0.0f; unsigned state = scramble % base; while (index) { unsigned digit = static_cast<unsigned>(index % base64), perm = (digit + state) % base; value = fmaf(static_cast<float>(perm), inv_pow, value); inv_pow = inv_base; index /= base64; state = (state * 1664525u + 1013904223u) % base; }return value < 1.0f ? value : 0.99999994f; }
static __declspec(noalias)__forceinline float agp_clamp_to_range(float v, float lo, float hi)noexcept { return v < lo ? lo : (v > hi ? hi : v); }
static __declspec(noalias) __forceinline unsigned long long agp_t_to_idx_open(const MortonND& map, float t) noexcept {
if (t <= 0.0f) return 0ull;
const unsigned long long idx =
static_cast<unsigned long long>(fmaf(t, static_cast<float>(map.scale), 0.0f));
return (idx < map.scale) ? idx : (map.scale - 1ull);
}
static __declspec(noalias)__forceinline void agp_write_seed_point(int row, int stride, int sobol_dims, int write_dim, const unsigned __restrict cur_x, const unsigned* __restrict scramble_mask, const int* __restrict perm_cache, const float* __restrict low_cache, const float* __restrict span_cache, float* __restrict S, unsigned long long index, const unsigned* __restrict halton_primes)noexcept { float* __restrict row_ptr = S + static_cast<size_t>(row) * static_cast<size_t>(stride); int dd = 0; while (dd < sobol_dims) { float u = static_cast<float>(cur_x[dd]) * 2.3283064e-10f; row_ptr[dd] = fmaf(u, span_cache[dd], low_cache[dd]); ++dd; }while (dd < write_dim) { unsigned base = halton_primes[(dd - AGP_SOBOL_BASE_DIMS) & 15]; float u = agp_radical_inverse_scrambled(index, base, scramble_mask[dd]); row_ptr[dd] = fmaf(u, span_cache[dd], low_cache[dd]); ++dd; }while (dd < stride) { row_ptr[dd] = 0.0f; ++dd; } }
static __declspec(noalias)__forceinline int generate_sobol_seeds_limited(const MortonND& map, int dim, float* __restrict S, int stride, unsigned seed, int max_points)noexcept {
if (max_points <= 0 || S == nullptr || stride <= 0 || dim <= 0)return 0; int dim_eff = dim < AGP_MAX_FULL_DIM ? dim : AGP_MAX_FULL_DIM, write_dim = stride < dim_eff ? stride : dim_eff; if (write_dim <= 0)return 0; int temp_dim = dim_eff - 1; if (temp_dim < 0)temp_dim = 0; int ns_orig = static_cast<int>(fmaf(static_cast<float>(temp_dim), fmaf(static_cast<float>(temp_dim), fmaf(static_cast<float>(temp_dim), fmaf(static_cast<float>(temp_dim), 0.00833333377f, 0.0416666679f), 0.16666667f), 0.5f), 1.0f)); int ns_pow2 = 1; while (ns_pow2 < ns_orig)ns_pow2 <<= 1; if (ns_pow2 > max_points)ns_pow2 = max_points; if (ns_pow2 <= 0)return 0;
static const unsigned int sobol_dir[AGP_MAX_FULL_DIM][32] = {
{ 1u, 3u, 5u, 7u, 9u, 11u, 13u, 15u, 17u, 19u, 21u, 23u, 25u, 27u, 29u, 31u,
33u, 35u, 37u, 39u, 41u, 43u, 45u, 47u, 49u, 51u, 53u, 55u, 57u, 59u, 61u, 63u },
{ 1u, 1u, 7u, 11u, 13u, 19u, 25u, 37u, 59u, 47u, 61u, 55u, 41u, 67u, 97u, 91u,
109u, 103u, 115u, 131u, 193u, 137u, 217u, 197u, 229u, 199u, 241u, 229u, 257u, 307u, 277u, 313u },
{ 1u, 3u, 5u, 7u, 9u, 11u, 13u, 15u, 17u, 19u, 21u, 23u, 25u, 27u, 29u, 31u,
33u, 35u, 37u, 39u, 41u, 43u, 45u, 47u, 49u, 51u, 53u, 55u, 57u, 59u, 61u, 63u },
{ 1u, 1u, 5u, 3u, 13u, 15u, 9u, 7u, 21u, 23u, 29u, 31u, 17u, 19u, 25u, 27u,
53u, 55u, 49u, 51u, 37u, 39u, 45u, 47u, 63u, 61u, 57u, 59u, 41u, 43u, 33u, 35u },
{ 1u, 3u, 3u, 7u, 13u, 3u, 13u, 7u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u },
{ 1u, 1u, 5u, 5u, 5u, 7u, 11u, 13u, 15u, 15u, 21u, 23u, 25u, 27u, 29u, 31u,
31u, 37u, 39u, 41u, 43u, 45u, 47u, 49u, 51u, 53u, 55u, 57u, 59u, 61u, 63u, 63u },
{ 1u, 3u, 5u, 5u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u,
7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u },
{ 1u, 1u, 7u, 5u, 13u, 13u, 17u, 19u, 21u, 23u, 25u, 27u, 29u, 31u, 35u, 37u,
39u, 41u, 43u, 45u, 49u, 51u, 53u, 55u, 57u, 59u, 61u, 63u, 65u, 67u, 69u, 71u },
{ 1u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u,
3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u, 3u },
{ 1u, 1u, 5u, 3u, 5u, 5u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u,
7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u },
{ 1u, 3u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u,
5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u },
{ 1u, 1u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u,
7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u },
{ 1u, 3u, 3u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u,
7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u },
{ 1u, 1u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u,
5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u, 5u },
{ 1u, 3u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u,
7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u, 7u },
{ 1u, 1u, 3u, 3u, 9u, 9u, 15u, 15u, 21u, 21u, 27u, 27u, 33u, 33u, 39u, 39u,
45u, 45u, 51u, 51u, 57u, 57u, 63u, 63u, 69u, 69u, 75u, 75u, 81u, 81u, 87u, 87u }
};
static const unsigned int halton_primes[AGP_MAX_FULL_DIM] = {
131u, 137u, 139u, 149u, 151u, 157u, 163u, 167u,
173u, 179u, 181u, 191u, 193u, 197u, 199u, 211u
};
alignas(32)unsigned scramble_mask[AGP_MAX_FULL_DIM]; alignas(32)int perm_cache[AGP_MAX_FULL_DIM]; alignas(32)float low_cache[AGP_MAX_FULL_DIM], span_cache[AGP_MAX_FULL_DIM]; int d = 0; while (d < dim_eff) { seed = agp_splitmix32(seed ^ (0x9E3779B9u + static_cast<unsigned>(d) * 0x85EBCA6Bu)); scramble_mask[d] = seed; ++d; }d = 0; while (d < write_dim) { int pd = map.perm[d]; float lo = map.low[pd]; perm_cache[d] = pd; low_cache[d] = lo; span_cache[d] = fmaf(map.high[pd], 1.0f, -lo); ++d; }unsigned long long start_idx = 1ull; int sobol_dims = dim_eff < AGP_SOBOL_BASE_DIMS ? dim_eff : AGP_SOBOL_BASE_DIMS; alignas(32)unsigned cur_x[AGP_SOBOL_BASE_DIMS]{}; d = 0; while (d < sobol_dims) { unsigned x = 0u; unsigned long long ii = start_idx; int b = 0; while (ii && b < 32) { if (ii & 1ull)x ^= sobol_dir[d][b]; ii >>= 1ull; ++b; }cur_x[d] = x ^ scramble_mask[d]; ++d; }agp_write_seed_point(0, stride, sobol_dims, write_dim, cur_x, scramble_mask, perm_cache, low_cache, span_cache, S, start_idx, halton_primes); unsigned long long prev_gray = start_idx ^ (start_idx >> 1ull); int j = 1; while (j < ns_pow2) { unsigned long long i = start_idx + static_cast<unsigned long long>(j), gray = i ^ (i >> 1ull), diff = gray ^ prev_gray; if (sobol_dims > 0) { int bit = _tzcnt_u64(diff); d = 0; while (d < sobol_dims) { cur_x[d] ^= sobol_dir[d][bit]; ++d; } }prev_gray = gray; agp_write_seed_point(j, stride, sobol_dims, write_dim, cur_x, scramble_mask, perm_cache, low_cache, span_cache, S, i, halton_primes); ++j; }return ns_pow2;
}
static __declspec(noalias)__forceinline int generate_sobol_seeds(const MortonND& map, int dim, float* __restrict S, int stride, unsigned seed)noexcept { return generate_sobol_seeds_limited(map, dim, S, stride, seed, AGP_MAX_GENERATED_SEEDS); }
static __declspec(noalias)__forceinline void ccd_ik(float targetX, float targetY, const float* lengths, int n, float* angles, int max_iter)noexcept { int nn = n < AGP_MAX_FULL_DIM ? n : AGP_MAX_FULL_DIM; alignas(32)float x[AGP_MAX_LINK_POINTS], y[AGP_MAX_LINK_POINTS], cum_angles[AGP_MAX_FULL_DIM], s_arr[AGP_MAX_FULL_DIM], c_arr[AGP_MAX_FULL_DIM]; int iter = 0; while (iter < max_iter) { float acc = 0.0f; int i = 0; while (i < nn) { acc += angles[i]; cum_angles[i] = acc; ++i; }FABE13_SINCOS(cum_angles, s_arr, c_arr, nn); float curX = 0.0f, curY = 0.0f; x[0] = y[0] = 0.0f; i = 0; while (i < nn) { curX = fmaf(lengths[i], c_arr[i], curX); curY = fmaf(lengths[i], s_arr[i], curY); x[i + 1] = curX; y[i + 1] = curY; ++i; }i = nn - 1; while (i >= 0) { float toEndX = x[nn] - x[i], toEndY = y[nn] - y[i], toTargetX = targetX - x[i], toTargetY = targetY - y[i], dot = fmaf(toEndX, toTargetX, toEndY * toTargetY), det = fmaf(toEndX, toTargetY, -toEndY * toTargetX), angle = atan2f(det, dot); float next = angles[i] + angle, lo = i == 0 ? -1.0471975511965976f : -2.6179938779914944f, hi = 2.6179938779914944f; angles[i] = next < lo ? lo : (next > hi ? hi : next); --i; }++iter; } }
static __declspec(noalias)__forceinline int generate_heuristic_seeds(const ManipCost& cost, const MortonND& map, int dim, float* __restrict S, int stride, unsigned seed)noexcept { int min_stride = (dim < AGP_MAX_SEED_STRIDE) ? dim : AGP_MAX_SEED_STRIDE; if (S == nullptr || stride < min_stride)return 0; int n = (cost.n < 32) ? cost.n : 32; bool VL = cost.variableLen; float tx = cost.targetX, ty = cost.targetY, phi = atan2f(ty, tx); bool is_transition = (cost.solveMode == ManipSolveMode::Transition) && cost.has_transition_reference_angles(); float dist_to_target = sqrtf(tx * tx + ty * ty), max_reach = 0.0f; if (VL) { for (int i = 0; i < n; ++i)max_reach += map.high[n + i]; } else { max_reach = static_cast<float>(n) * cost.fixedLength; }float ratio = dist_to_target / fmaxf(max_reach, 1e-20f); bool prefer_extended = (ratio > 0.7f), prefer_compact = (ratio < 0.4f), use_ik = !(ratio > 0.4f && ratio < 0.7f); int total_seeds = 0; auto emit_seed = [&](const float* q_src)noexcept->bool {if (total_seeds >= AGP_MAX_GENERATED_SEEDS)return false; float* dst = S + static_cast<size_t>(total_seeds) * static_cast<size_t>(stride); agp_copy_state_clamped_to_map(q_src, map, dim, dst); ++total_seeds; return true; }; if (is_transition) { alignas(32)float q_ref[AGP_MAX_FULL_DIM]{}, q_blend[AGP_MAX_FULL_DIM]{}, q_taper[AGP_MAX_FULL_DIM]{}; int full_dim = cost.full_state_dim(); int d = 0; while (d < full_dim) { if (d < cost.referenceStateCount)q_ref[d] = cost.referenceState[d]; else if (d < n)q_ref[d] = 0.0f; else q_ref[d] = cost.fixedLength; ++d; }while (d < AGP_MAX_FULL_DIM) { q_ref[d] = 0.0f; ++d; }emit_seed(q_ref); d = 0; while (d < full_dim) { q_blend[d] = q_ref[d]; q_taper[d] = q_ref[d]; ++d; }float per_joint_phi = (n > 0) ? (phi / static_cast<float>(n)) : 0.0f; d = 0; while (d < n) { float t01 = (n > 1) ? (static_cast<float>(d) / static_cast<float>(n - 1)) : 0.0f, blend = fmaf(0.20f, t01, 0.08f); q_blend[d] = fmaf(blend, per_joint_phi - q_ref[d], q_ref[d]); q_taper[d] = q_ref[d] * fmaf(-0.12f, t01, 1.0f); ++d; }emit_seed(q_blend); emit_seed(q_taper); if (use_ik && prefer_extended && total_seeds < AGP_MAX_GENERATED_SEEDS) { alignas(32)float q_ccd[AGP_MAX_FULL_DIM]{}; float angles[AGP_MAX_FULL_DIM]{}, lengths[AGP_MAX_FULL_DIM]{}; if (VL) { float avg_len = 0.5f * (map.low[n] + map.high[n]); for (int i = 0; i < n; ++i)lengths[i] = avg_len; } else { for (int i = 0; i < n; ++i)lengths[i] = cost.fixedLength; }ccd_ik(tx, ty, lengths, n, angles, 10); for (int i = 0; i < n; ++i) { float blend = 0.30f; q_ccd[i] = fmaf(blend, angles[i] - q_ref[i], q_ref[i]); }if (VL) { for (int i = 0; i < n; ++i) { q_ccd[n + i] = fmaf(0.30f, lengths[i] - q_ref[n + i], q_ref[n + i]); } }emit_seed(q_ccd); }int remaining = AGP_MAX_GENERATED_SEEDS - total_seeds; if (remaining > 0)total_seeds += generate_sobol_seeds_limited(map, dim, S + static_cast<size_t>(total_seeds) * static_cast<size_t>(stride), stride, seed, remaining); return total_seeds; } { alignas(32)float q0[AGP_MAX_FULL_DIM]{}; float rho = sqrtf(fmaf(tx, tx, ty * ty)), len = fmaf(1.0f / static_cast<float>(fmaxf(static_cast<float>(n), 1.0f)), rho, 0.0f); int i = 0; while (i < n) { q0[i] = agp_clamp_to_range((1.0f / static_cast<float>(n)) * phi, map.low[i], map.high[i]); ++i; }if (VL) { i = 0; while (i < n) { q0[n + i] = agp_clamp_to_range(len, map.low[n + i], map.high[n + i]); ++i; } }emit_seed(q0); } { alignas(32)float q1[AGP_MAX_FULL_DIM]{}; int i = 0; while (i < n) { q1[i] = agp_clamp_to_range(0.5f * phi * ((i & 1) ? -1.0f : 1.0f), map.low[i], map.high[i]); ++i; }if (VL) { i = 0; while (i < n) { q1[n + i] = agp_clamp_to_range(fmaf(0.4f, static_cast<float>(i) / static_cast<float>(fmaxf(static_cast<float>(n), 1.0f)), 0.8f), map.low[n + i], map.high[n + i]); ++i; } }emit_seed(q1); } { alignas(32)float q2[AGP_MAX_FULL_DIM]{}; float inv = (n > 1) ? 1.0f / static_cast<float>(n - 1) : 0.0f; int i = 0; while (i < n) { float pr = static_cast<float>(i) * inv; q2[i] = agp_clamp_to_range(fmaf(phi, fmaf(-0.3f, pr, 1.0f), 0.0f), map.low[i], map.high[i]); ++i; }if (VL) { int j = 0; while (j < n) { float si; FABE13_SIN(fmaf(1.5f, static_cast<float>(j), 0.0f), si); q2[n + j] = agp_clamp_to_range(fmaf(0.2f, si, 1.0f), map.low[n + j], map.high[n + j]); ++j; } }emit_seed(q2); }if (use_ik && prefer_extended && total_seeds < AGP_MAX_GENERATED_SEEDS) { alignas(32)float q3[AGP_MAX_FULL_DIM]{}; float angles[AGP_MAX_FULL_DIM]{}, lengths[AGP_MAX_FULL_DIM]{}; if (VL) { float avg_len = 0.5f * (map.low[n] + map.high[n]); for (int i = 0; i < n; ++i)lengths[i] = avg_len; } else { for (int i = 0; i < n; ++i)lengths[i] = cost.fixedLength; }ccd_ik(tx, ty, lengths, n, angles, 10); int i = 0; while (i < n) { q3[i] = agp_clamp_to_range(angles[i], map.low[i], map.high[i]); ++i; }if (VL) { i = 0; while (i < n) { q3[n + i] = agp_clamp_to_range(lengths[i], map.low[n + i], map.high[n + i]); ++i; } }emit_seed(q3); }if (use_ik && prefer_compact && total_seeds < AGP_MAX_GENERATED_SEEDS) { alignas(32)float q4[AGP_MAX_FULL_DIM]{}; float angles_fabrik[AGP_MAX_FULL_DIM]{}, lengths_fabrik[AGP_MAX_FULL_DIM]{}; if (VL) { float avg_len = 0.5f * (map.low[n] + map.high[n]); for (int i = 0; i < n; ++i)lengths_fabrik[i] = avg_len; } else { for (int i = 0; i < n; ++i)lengths_fabrik[i] = cost.fixedLength; }float targetX_fab = tx, targetY_fab = ty; for (int iter_fab = 0; iter_fab < 3; ++iter_fab) { float prevX = targetX_fab, prevY = targetY_fab; for (int j = n - 1; j >= 0; --j) { float len = lengths_fabrik[j], angle_to_target = atan2f(prevY, prevX); angles_fabrik[j] = angle_to_target; float s_val, c_val; FABE13_SINCOS(&angle_to_target, &s_val, &c_val, 1); prevX = prevX - len * c_val; prevY = prevY - len * s_val; } }int i = 0; while (i < n) { q4[i] = agp_clamp_to_range(angles_fabrik[i], map.low[i], map.high[i]); ++i; }if (VL) { i = 0; while (i < n) { q4[n + i] = agp_clamp_to_range(lengths_fabrik[i], map.low[n + i], map.high[n + i]); ++i; } }emit_seed(q4); }int remaining = AGP_MAX_GENERATED_SEEDS - total_seeds; if (remaining > 0)total_seeds += generate_sobol_seeds_limited(map, dim, S + static_cast<size_t>(total_seeds) * static_cast<size_t>(stride), stride, seed, remaining); return total_seeds; }
" - проверь тут всё очень тщательно и внимательно, будь очень бдителен так как я уверен что ошибка имеет именно типичный характер обращения к памяти за пределами диапазона, если в этом коде будут встречаться другие константы то вот они: "static constexpr int AGP_MAX_FULL_DIM = 16;
static constexpr int AGP_MAX_LINK_POINTS = AGP_MAX_FULL_DIM + 1;
static constexpr unsigned AGP_MULTI_INTERVAL_STRIDE = 5u;
static constexpr unsigned AGP_MULTI_INTERVAL_MAX_COUNT = 7u;
static constexpr unsigned AGP_MULTI_INTERVAL_FLOATS = AGP_MULTI_INTERVAL_STRIDE * AGP_MULTI_INTERVAL_MAX_COUNT;
#define AGP_BYTES_F32(n) (static_cast<SIZE_T>(n) << 2)
#define AGP_ASSIGN_DIM(dst,src,dim) do{(dst).resize(static_cast<size_t>(dim));std::memcpy((dst).data(),(src),AGP_BYTES_F32(dim));}while(0)"
pythondef ns(temp_dim): return int(temp_dim*(temp_dim*(temp_dim*(temp_dim*0.00833333377+0.0416666679)+0.16666667)+0.5)+1.0) for t in range(16): print(t, ns(t))
Да — в этом фрагменте есть несколько реальных, не гипотетических мест, где возможен выход за границы массива. Причём как минимум два из них выглядят как очень типичный источник 0xC0000005 / AccessViolation.
Самое важное: краш вполне может проявляться не в месте порчи памяти, а позже, поэтому стек с RunAgpCppAtPoint(...) не опровергает, что ломается именно здесь.
generate_sobol_seeds_limited → agp_write_seed_pointУ вас сейчас так:
cppint dim_eff = dim < AGP_MAX_FULL_DIM ? dim : AGP_MAX_FULL_DIM; int write_dim = stride < dim_eff ? stride : dim_eff; ... int sobol_dims = dim_eff < AGP_SOBOL_BASE_DIMS ? dim_eff : AGP_SOBOL_BASE_DIMS;
При этом в agp_write_seed_point:
cppwhile (dd < sobol_dims) { float u = static_cast<float>(cur_x[dd]) * 2.3283064e-10f; row_ptr[dd] = fmaf(u, span_cache[dd], low_cache[dd]); ++dd; }
Если stride < dim_eff, то:
write_dim = stridesobol_dims = dim_effТо есть цикл пишет до dd < dim_eff, хотя строка реально имеет только stride элементов:
cppfloat* row_ptr = S + row * stride;
В этом случае у вас одновременно происходят две ошибки:
row_ptr[dd] при dd >= stridespan_cache[dd], low_cache[dd] инициализируются только до write_dim, а читаются до sobol_dimsЭто очень сильный кандидат на вашу проблему.
Либо жёстко запрещать такой вызов:
cppif (stride < dim_eff) return 0;
либо, если частичная запись допустима, то хотя бы так:
cppconst int sobol_dims = (write_dim < AGP_SOBOL_BASE_DIMS) ? write_dim : AGP_SOBOL_BASE_DIMS;
Сейчас именно это место у вас небезопасно.
generate_heuristic_seeds размер всех локальных буферов = 16, а n вы разрешаете до 32Вот это уже совсем серьёзно:
cppint n = (cost.n < 32) ? cost.n : 32;
Но дальше у вас почти все массивы имеют размер AGP_MAX_FULL_DIM == 16:
cppalignas(32) float q0[AGP_MAX_FULL_DIM]{}; alignas(32) float q1[AGP_MAX_FULL_DIM]{}; alignas(32) float q2[AGP_MAX_FULL_DIM]{}; alignas(32) float q3[AGP_MAX_FULL_DIM]{}; alignas(32) float q4[AGP_MAX_FULL_DIM]{}; alignas(32) float q_ref[AGP_MAX_FULL_DIM]{}, q_blend[AGP_MAX_FULL_DIM]{}, q_taper[AGP_MAX_FULL_DIM]{}; float angles[AGP_MAX_FULL_DIM]{}, lengths[AGP_MAX_FULL_DIM]{}; float angles_fabrik[AGP_MAX_FULL_DIM]{}, lengths_fabrik[AGP_MAX_FULL_DIM]{};
cost.n > 16, то фиксированно возникают записи вида:
q0[i], q1[i], q2[i], q3[i], q4[i]lengths[i], angles[i]lengths_fabrik[i], angles_fabrik[i]variableLen == trueТам вы используете индексы вида n + i:
cppq0[n + i] q1[n + i] q2[n + i] q3[n + i] q4[n + i] q_ccd[n + i] q_ref[n + i]
При массиве размера 16 это безопасно только если:
2 * n <= 16n <= 8Иначе порча памяти гарантирована.
Если у вас:
n <= 16n <= 8А код сейчас допускает n <= 32.
Это не “возможно”, это реальный баг по дизайну размерностей.
emit_seed() может читать за пределами локальных q*-массивовУ вас:
cppauto emit_seed = [&](const float* q_src) noexcept -> bool { if (total_seeds >= AGP_MAX_GENERATED_SEEDS) return false; float* dst = S + static_cast<size_t>(total_seeds) * static_cast<size_t>(stride); agp_copy_state_clamped_to_map(q_src, map, dim, dst); ++total_seeds; return true; };
Но q_src почти всегда — это один из локальных массивов размера 16:
cppfloat q0[16], q1[16], q2[16], ...
Если dim > 16, то agp_copy_state_clamped_to_map(q_src, map, dim, dst) почти наверняка будет читать q_src[16], q_src[17], ... за пределами массива.
То есть даже если предыдущие циклы случайно “не заденут” память, здесь всё равно есть очень вероятный OOB-read.
full_dim вообще не ограничен 16Вот это место тоже опасно:
cppint full_dim = cost.full_state_dim(); int d = 0; while (d < full_dim) { if (d < cost.referenceStateCount) q_ref[d] = cost.referenceState[d]; else if (d < n) q_ref[d] = 0.0f; else q_ref[d] = cost.fixedLength; ++d; }
Но q_ref размером 16.
Если full_dim > 16, вы гарантированно пишете за пределы q_ref.
Дальше то же самое для:
cppq_blend[d] = q_ref[d]; q_taper[d] = q_ref[d];
То есть transition-ветка сама по себе уже может ломать стек/память.
agp_t_to_idx_openЭто не из сидов напрямую, но это тоже memory-danger:
cppif (t <= 0.0f) return 0ull; const unsigned long long idx = static_cast<unsigned long long>(fmaf(t, static_cast<float>(map.scale), 0.0f)); return (idx < map.scale) ? idx : (map.scale - 1ull);
Если map.scale == 0, то при t > 0 вернётся:
cppmap.scale - 1ull
то есть ULLONG_MAX.
Если этот индекс потом используется для доступа в массив/таблицу — получите выход далеко за границы.
cost.n > 16То generate_heuristic_seeds() у вас точно небезопасна.
variableLen == true и cost.n > 8То там точно есть OOB через индексы n + i.
stride < dimТо generate_sobol_seeds_limited() / agp_write_seed_point() тоже точно небезопасны.
generate_sobol_seeds_limitedcppstatic __declspec(noalias)__forceinline int generate_sobol_seeds_limited( const MortonND& map, int dim, float* __restrict S, int stride, unsigned seed, int max_points) noexcept { if (max_points <= 0 || S == nullptr || stride <= 0 || dim <= 0) return 0; const int dim_eff = (dim < AGP_MAX_FULL_DIM) ? dim : AGP_MAX_FULL_DIM; // Если это инвариант дизайна — лучше так: if (stride < dim_eff) return 0; const int write_dim = dim_eff; if (write_dim <= 0) return 0; ... const int sobol_dims = (write_dim < AGP_SOBOL_BASE_DIMS) ? write_dim : AGP_SOBOL_BASE_DIMS; ... }
generate_heuristic_seedsНужно либо жёстко валидировать размерность, либо расширять все массивы и всю логику.
Безопасная валидация:
cppconst bool VL = cost.variableLen; const int max_n = VL ? (AGP_MAX_FULL_DIM / 2) : AGP_MAX_FULL_DIM; if (cost.n < 0 || cost.n > max_n) return 0; const int n = cost.n; const int full_dim = VL ? (2 * n) : n; if (dim != full_dim) return 0; if (dim > AGP_MAX_FULL_DIM) return 0; if (stride < dim) return 0; if (cost.full_state_dim() != full_dim) return 0;
И только после этого использовать локальные массивы размера 16.
У вас вся эта подсистема по факту рассчитана максимум на 16 координат состояния:
AGP_MAX_FULL_DIM = 16sobol_dir[16][32]halton_primes[16]q*, angles, lengths, scramble_mask, low_cache, span_cache — тоже 16Но при этом generate_heuristic_seeds() позволяет n до 32.
То есть проблема не в одном случайном индексе — у вас здесь есть системная несовместимость размерностей.
В этом фрагменте я вижу минимум 4 реальных memory-bug источника:
agp_write_seed_point() пишет до sobol_dims, хотя реально подготовлено только write_dimgenerate_heuristic_seeds() допускает n до 32 при локальных массивах размера 16emit_seed() может читать больше 16 элементов из q_srcfull_dim в transition-ветке не ограничен 16Если хочешь, следующим сообщением я могу дать тебе уже готовую исправленную версию этих двух функций (generate_sobol_seeds_limited и generate_heuristic_seeds) в безопасном виде, без переписывания всей остальной архитектуры.