c++ - -O3 模式下的段错误?

标签 c++ gcc optimization segmentation-fault

我将我的问题总结为以下短程序。

它仅在 -O3 模式下导致 SEGFAULT(-O2 工作正常)。 根据 gdb,它发生在 *f = 0 行。

#include <iostream>

void func1(int s, int t)
{
        char* buffer = new char[s + t*sizeof(float)];
        if (!buffer)
        {
            std::cout << "new failed\n";
            return;
        }
        float* f = (float*)(buffer + s);
        for (int i = 0; i < t; ++i)
        {
            *f = 0;
            //std::cout << i << std::endl; // if uncomment this line everything will work fine
            ++f;
        }
        delete [] buffer;
        std::cout << "done\n";
}

int main()
{
        int s = 31, t = 12423138;
        std::cout << s << " " << t << std::endl;
        func1(s, t);
        return 0;
}

请告诉我,我做错了什么?

最佳答案

SEGFAULT 的来源不仅仅违反了严格的别名规则,因为即使使用 -fno-strict-aliasing 标志,问题仍然存在。

确实是在访问未对齐的内存,但并没有这么简单。作为现代处理器,通常允许未对齐的内存访问,现在甚至没有太多开销。我已经完成了一些基准测试,并没有观察到我的 Intel(R) Xeon(R) CPU E5-2680 v2 @ 2.80GHz 上的对齐读取与未对齐读取有很大差异。还有some网络中的结果非常相似(或多或少最近)。

我的问题是 -O3 模式启用了 -ftree-vectorize 标志,因此我的 for 循环被矢量化了(正如我看到的使用-ftree-vectorizer-verbose 标志)。并且(AFAIU)不支持(还?)使用向量化指令进行未对齐的内存访问,因此出现运行时异常。

This article在理解理论方面帮助了我很多,尽管今天未对齐的内存访问似乎不像以前那样有害,但仍然很棘手

关于c++ - -O3 模式下的段错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33843444/

相关文章:

c++ - 前缀计算器——在某些情况下不起作用——C++

c# - 监视未使用的局部变量是不可能的?为什么?

ios - 优化 - 步进可能表现得很奇怪 : iOS/Unity

c++ - 有符号到无符号转换,并返回,整数的定义行为?

c++ - 从 C++ 到 OpenCL 的指针

c++ - C++十进制类型和括号-为什么?

c++ - g++ 不允许使用标识符中的😃(和其他 Unicode 字符)

c - 适用于AVX512掩码寄存器(k1 ... k7)的GNU C内联asm输入约束?

iphone - 为 iPhone 交叉编译 libgcrypt?链接器错误...似乎找不到 "fwrite"和 "strerror"?

optimization - 您可以在一个 Redis 实例中插入多少条记录?