std :: array类上的堆栈溢出 [英] Stack overflow on std::array class

查看:78
本文介绍了std :: array类上的堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾经做过一些C#和Java,但是最近我想学习c ++,而且我发现许多大型公司都喜欢c ++,因为它的效率很高.

I used to do some C# and Java, but lately I wanted to learn c++ as well as I found out many large company prefer c++ for its efficiency.

试图适应C ++的语法和行为,我开始将用Java完成的测试转换为C ++代码,以下是其中之一:

Trying to get used to the syntax and behaviour of C++, I started to translate the test I done in Java to C++ code, and the following is one of them:

#include "stdafx.h"
#include <iostream>
#include <array>
#include <string>
#include <cstring>
#include <chrono>
using namespace std;
using namespace std::chrono;

typedef array<array<int, 1000>, 1000> aArray;

aArray hasLocality(aArray, aArray);
aArray noLocality(aArray, aArray);

static aArray a = aArray();
static aArray b = aArray();

int main() {

    for (size_t i = 0; i < 100; i++)
    {
        for (size_t j = 0; j < 100; j++)
        {
            a[i][j] = i + j;
            b[i][j] = i + j;
        }
    }
    hasLocality(a, b);
    noLocality(a, b);
    system("pause");
    return 0;
}

aArray hasLocality(aArray a, aArray b) {
    milliseconds startTime = duration_cast<milliseconds>(
        system_clock::now().time_since_epoch()
        );
    aArray ans = aArray();
    for (size_t i = 0; i < ans.size(); i++)
    {
        for (size_t k = 0; k < ans[0].size(); k++)
        {
            for (size_t j = 0; j < ans[0].size(); j++)
            {
                ans[i][j] = ans[i][j] + a[i][k] * b[k][j];
            }
        }
    }

    milliseconds endTime = duration_cast<milliseconds>(
        system_clock::now().time_since_epoch()
        );
    string time = std::to_string((endTime - startTime).count()) + "\n";
    cout.write(time.c_str(), (unsigned)strlen(time.c_str()));
    return ans;
}

aArray noLocality(aArray a, aArray b) {
    milliseconds startTime = duration_cast<milliseconds>(
        system_clock::now().time_since_epoch()
        );
    aArray ans = aArray();
    for (size_t i = 0; i < ans.size(); i++)
    {
        for (size_t j = 0; j < ans[0].size(); j++)
        {
            for (size_t k = 0; k < ans[0].size(); k++)
            {
                ans[i][j] = ans[i][j] + a[i][k] * b[k][j];
            }
        }
    }
    milliseconds endTime = duration_cast<milliseconds>(
        system_clock::now().time_since_epoch()
        );
    string time = std::to_string((endTime - startTime).count()) + "\n";
    cout.write(time.c_str(), (unsigned)strlen(time.c_str()));
    return ans;
}

这是我通过执行简单矩阵乘法进行的局部性测试之一,但是由于数组过大,我无法摆脱堆栈溢出异常,我认为这对于测试至关重要.

This is one of my test on locality by doing simple matrix multiplication, however I can't get rid of stack overflow exception because of the excessive large array size, which I think is essential for the test.

我还认为该数组将被放置在堆上,而不是放在堆栈上,因为我将其放置为静态.

I also thought the array would be placed on heap instead of stack as I put it as static.

最后,我发现当给定较小的数组大小(100、100),异常数量或不足时, noLocality hasLocality 更有效.本地化的数据?

At last, I found that the noLocality is more efficient than hasLocality when given a smaller array size (100, 100), was that abnormal or just insufficient amount of data for locality to take place?

预先感谢

推荐答案

在Java中,所有对象参数都是通过引用传递的.在C ++中,默认值是按值传递它们(即,将副本放置在堆栈中).因此,当您致电:

In Java, all object arguments are passed by reference. In C++, the default is that they are passed by value (ie a copy is placed on the stack). So when you call:

aArray hasLocality(aArray a, aArray b)

最后在堆栈上得到a的副本,然后是b的副本,并且还为返回值(aArray的另一副本)分配了空间.您在堆栈上分配了3个大型数组.这与Java不同.

You end up with a copy of a on the stack followed by a copy of b, and you also have space allocated for the return value, another copy of an aArray. You have 3 massive arrays allocated on the stack. This is different from Java.

在C ++中,可以避免使用引用或指针按值传递.Java没有指针.Java引用与C ++引用并不完全相同,但是有相似之处.

In C++ you can avoid passing by value by using references or pointers. Java does not have pointers. Java references are not quite the same as C++ references, but there are similarities.

所以,如果您有:

aArray hasLocality(aArray &a, aArray &b)

然后您得到类似于Java的东西,该数组通过引用传递,与Java中相同.对hasLocality的调用没有什么不同.因此,只需以这种方式更改hasLocality和noLocality即可.您仍然具有返回值副本.为了避免这种情况,您可以做的一件事就是同时传递返回值:

then you end up with something similar to Java, the arrays are passed by reference, same as in Java. Calls to hasLocality are no different. So just change hasLocality and noLocality in this way. You still have the return value copy. To avoid that, one thing you can do is pass in the return value as well:

void hasLocality(aArray &a, aArray &b, aArray &ans)

然后移动

aArray ans = aArray();

功能之外.

到那时,您将不会再进行数组复制,就像Java一样.但是请记住,C ++中的引用有些不同,一旦引用引用了一个对象,就无法引用任何其他对象.由于您是C ++的新手,这可能会使您感到困惑,但是您会学到的.请注意,C ++总体上比Java更复杂.

At that point you'd have no array copying going on, just like Java. But do keep in mind references in C++ are a bit different, once a reference refers to an object, it cannot refer to any other object. Since you're new to C++ this might confuse you right now, but you'll learn. Note that C++ is more complicated than Java overall.

这篇关于std :: array类上的堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆