在有足够空间的情况下加载到数组会导致堆栈粉碎?

Posted

技术标签:

【中文标题】在有足够空间的情况下加载到数组会导致堆栈粉碎?【英文标题】:Loading into Array causes Stack Smashing while having enough space? 【发布时间】:2019-05-20 05:42:47 【问题描述】:

执行以下代码时,我收到 Stack Smashing 错误。

const uint size = 62;

...
for (int i=0; i < 10; ++i)
    // mask = elements != zero
    // input = epi32 m512 data containing 1 byte values
    _mm512_mask_compress_epi32(input, mask, input);
    // get just elements != 0 as previous mask. 
    __mmask16 mask1 = _mm512_cmpneq_epi32_mask(compressed, _mm512_setzero_epi32());
    // append the non-zero elements to the uchar* 
    _mm512_mask_cvtusepi32_storeu_epi8((uchar*)str+pos, mask1, compressed); // uncommenting = no error, truncating mask = no error

     // add size of the inserted elements by counting 1's in mask
     pos += sizeOfInsertion;

     // print the position of the pointer AFTER storing
     void* pp = (void*) ((uchar*) str + pos);
     std::cout << pp << std::endl;

为了调查这个问题,我在插入元素时检查了指针的位置。 开头(pointing to str[0]) 我有0x7ffce3468d30,结尾有0x7ffce3468d69。减去这些地址,我得到3E = 62。所以它应该适合声明的数组。 将掩码移动 1(截断一个元素),它不会引发错误。

【问题讨论】:

此代码未显示您如何计算 sizeOfInsertion 或任何变量,或者您如何生成 compressed。即它缺少minimal reproducible example。此外,如果您的答案确实以某种方式回答了这个问题,那么您为什么要在 vpcompressd 之后重新计算掩码?您不能只使用您用于左包装的现有__mask16 来满足您的缩小吗?此外,AVX512 还可以测试元素的零/非零,而无需与零寄存器进行比较。例如mask = _mm512_test_epi32_mask(same,same) 您应该将缺失的部分添加到问题中,以便人们可以看到@Sapp 的所有内容 谢谢,我只是添加了一些额外的解释。重新计算是因为输入数据中的数据不需要是连续的,因此掩码可能类似于1100 0110 0101 0011。压缩后数据是连续的,因此掩码类似于1111 1111 0000 0000。感谢使用_mm512_test_epi32_mask 的提示。 哦,对,是的,您需要左打包或重新计算掩码。或者,如果您可以填充数组,您也可以只进行未屏蔽的部分重叠 128 位存储。 【参考方案1】:

失败在于压缩。我不介意将不匹配掩码的值归零,因此数据没有连续存储,因此堆栈溢出。

简而言之:

_mm512_maskz_compress_epi32(mask, input);

让它工作。

【讨论】:

您不需要将合并掩码合并到归零寄存器中,您可以使用_mm512_maskz_compress_epi32 进行零掩码而不是合并掩码。 (或者甚至 _mm512_mask_compressstoreu_epi32 将掩码存储到内存中)。 谢谢,刚刚按照你的建议改了。

以上是关于在有足够空间的情况下加载到数组会导致堆栈粉碎?的主要内容,如果未能解决你的问题,请参考以下文章

使用自动布局将视图浮动到第二行

代码在我的系统上运行良好,但是当我将它提交给应该检查它的机器人时会导致堆栈粉碎错误

检测到堆栈粉碎 glGetTexImage

递归代码在数组列表偏大的情况下会导致堆栈溢出。一个解决办法

使用 c++ 偶尔检测到 *** 堆栈粉碎***

istream 的tellg/seekg 无法防止堆栈粉碎(g++)?