【问题标题】:ostream crash using aligned memory on heap?ostream 在堆上使用对齐内存崩溃?
【发布时间】:2019-07-02 21:47:34
【问题描述】:

这是我的一个虚拟代码,用“巨大”值测试堆上对齐的内存分配:

#include <iostream>
#include <iomanip>
#include <immintrin.h>

const double ln2per12 = std::log(2.0) / 12.0;

class ApproxExp
{
public:
    long step = 1000;
    long min = -48 * step;
    long max = 48 * step;
    long range = max - min;
    long numSteps = range + 1;

    __m128 v_value_float;

    float *approxFreqMuls_Float = static_cast<float*>(_mm_malloc(sizeof(float) * numSteps, 16));

    ApproxExp() {
        long inc = min;

        for (long i = 0; i < numSteps; i++, inc++) {
            double pitch = inc / (double)step;
            double refValue = pitch * ln2per12;

            v_value_float.m128_f32[i % 4] = (float)refValue;
            if (i % 4 == 3 || i == numSteps - 1) {
                _mm_store_ps(&approxFreqMuls_Float[i % 4 == 3 ? i - 3 : i - i % 4], v_value_float);
            }
        }

        std::cout << "oct       ";
    }
    ~ApproxExp() {
        _mm_free(approxFreqMuls_Float);
    }
};

int main() {
    std::cout.precision(100);
    std::cout << std::left;

    ApproxExp approxExp;

    return 0;
}

当我执行它时,“有时”它会粗暴地中断(发布模式,MSVC),显示如下:

我无法找到错误,因为我没有看到任何异常代码。我哪里错了?

【问题讨论】:

  • 我在您的代码中没有看到任何ostream 的使用。你能把它包括进去吗?
  • @NathanOliver:我有一个简单的std::cout &lt;&lt; "oct ";。一旦我调用它,它就会崩溃(有时......)
  • 看起来你肯定在某个地方有 UB。
  • 当然可以,但我想知道你为什么一开始就写这个。正如答案所暗示的那样,您可能在这里弄错了索引逻辑并且正在写入数组末尾。 (或者提供_mm_store_ps 一个未对齐的地址?)当你使用调试器时,它到底在哪里崩溃? (局部变量和/或寄存器的值)
  • @markzzz 为什么你不能将对话框的文本复制到你的问题中?是文字,不是吗?即使你不能剪切'n'粘贴它,你仍然可以手写它。这并不难;发布文字,而不是图片。文本可搜索,图像不可搜索。文本是 in 的问题,imagws 在可能会死掉的链接后面。把它写下来。

标签: c++ windows sse simd memory-alignment


【解决方案1】:

如果到达最后一个索引并且其余数不是 3,则在索引 i - i % 4 处写入 128 位会写入数组外部。
然后你就进入了未定义行为的美妙之地。

【讨论】:

    猜你喜欢
    • 2019-08-11
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    • 2011-06-25
    • 2011-08-02
    • 2018-04-03
    • 2012-03-17
    • 1970-01-01
    相关资源
    最近更新 更多