【问题标题】:Summing over large array returns 0 in C/C++在 C/C++ 中对大数组求和返回 0
【发布时间】:2018-02-14 04:14:20
【问题描述】:

我有一个简单的例子,对数组求和:

static uint64_t ySumSimple(uint32_t* arr, uint32_t* to) {
    uint64_t sum = 0;

    while (arr < to) {
        sum = sum + *arr;
        ++arr;
    }

    return sum;
}

并在 main 方法中使用它,例如:

using namespace std;
int main(){

    size_t size = 1000*1000;// len*loops;

    uint32_t * arr= (uint32_t *) malloc(size * sizeof(uint32_t));// random values here          

    auto sum = ySumSimple(arr,arr+size);

    cout <<" sum " <<  sum << endl;
}

如果 size = 1000*100,这将返回实际总和(某个大数字),但对于一百万个 uint,它返回 0。如果超过一百万个 uint 的总和不能溢出 ulong,那怎么会呢?

【问题讨论】:

  • 没有“C/C++”之类的东西。
  • 对未定义的行为一无所知,实际的解释可能与如何分配各种大小的内存块有关。许多 C++ 运行时实现在进程内保留一个较小的内存块池,以便有效地重用,但是当您 malloc() 真正大量的内存时,它们会退回到直接从操作系统的空闲存储中分配内存。为了避免安全问题(例如,非特权应用程序 A 读取特权应用程序 B 的秘密但免费()数据),操作系统免费存储的内存通常在分配给应用程序之前清零。

标签: c++


【解决方案1】:

由于您使用 C++ 编程(请删除 C 语言标签),您拥有undefined behavior

您有 UB,因为虽然您分配的内存内容可能看起来是随机的,但它的实际内容是不确定的。并且使用(甚至只是阅读)indeterminate 数据会导致 UB。

【讨论】:

  • 我猜,肯定只是随机值,还有什么可能导致它
  • @user184868 是否“随机”无关紧要。它是未初始化的,因此是不确定的,因此你有未定义的行为。如果你有未定义的行为,那么争论行为真的没有意义。
  • 未定义的行为并不意味着将读取随机值。如果分配的内存是来自操作系统的新页面,您可能会得到 0。有些架构甚至不允许您访问未初始化的内存
  • 关于操作系统页面的好点,似乎超过 100k 的值在新的?在那里设置一些值时如何没有错误,谢谢
【解决方案2】:

以下所有这些值均保持零 (0)。因此它们的总和为零!

*arr 为零 *(arr+1) 为零 ... *(arr+size) 为零

首先求和将给出零。您需要在数组arr 中赋值。

在下面找到更正的代码(包含数组元素值的分配),总和为 499999500000。

#include <iostream>
using namespace std;

static uint64_t ySumSimple(uint32_t* arr, uint32_t* to) {
    uint64_t sum = 0;

    while (arr < to) {
        sum = sum + *arr;
        ++arr;
    }

    return sum;
}


int main() {
    size_t size = 1000*1000;// len*loops;

    uint32_t * arr= (uint32_t *) malloc(size * sizeof(uint32_t));// random values here          

    //Assign Values into the array elements
    for(int i=0; i< size; i++)
        *(arr+i) = i;

    auto sum = ySumSimple(arr,arr+size);


    cout <<" sum " <<  sum << endl;
    return 0;
}

【讨论】:

    猜你喜欢
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 2018-07-15
    • 2018-01-17
    • 1970-01-01
    • 2011-12-17
    相关资源
    最近更新 更多