admin管理员组

文章数量:1126325

In some code I have written, a new FenwickTree is constructed from a vector ind that remains the same size every loop. The FenwickTree size is the same as the input vector. Will the compiler optimize not repeatedly at the start of the loop constructing the object and allocating memory, then destructing the object at the end of the loop? I am more familiar with C where memory management is explicit.

Example

#include <vector>
#include <iostream>

struct fenwick_tree
{
    size_t len; // 0-based len
    std::vector<int> t; // 1-based tree, indexes [1:len]

    fenwick_tree(std::vector<int> const &a) :
    len(a.size()), t(len + 1, 0) 
    {
        for (size_t i = 0; i < len; ++i)
            add_to(i, a[i]);
    }

    // 0-based input
    int sum_to(size_t r) const
    {
        int s = 0;
        for (++r; r > 0; r -= r & -r)
            s += t[r];
        return s;
    }

    // 0-based input
    void add_to(size_t i, int delta)
    {
        for (++i; i <= len; i += i & -i)
            t[i] += delta;
    }
};

int main()
{
    std::vector<int> ind(10, 10);
    for (int i = 1; i < 10; ++i)
    {
        ind.assign(10, 10*i);
        auto fen = fenwick_tree(ind);

        std::cout << fen.sum_to(9) << std::endl;
    }
}

This is the result of ltrace. I can see memset and flush, but I can't tell if

_ZNSt8ios_base4InitC1Ev(0x58659f9b8151, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d30) = 0x72f4c90224b8
__cxa_atexit(0x72f4c92bf840, 0x58659f9b8151, 0x58659f9b8008, 0x72f4c942ada0)          = 0
_Znwm(40, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d38)                             = 0x5865aab3ceb0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 100, 2, 10)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 0x7ffd6d84bac8100
)                       = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 200, 2, 20)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3122200
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 300, 2, 30)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3123300
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 400, 2, 40)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3124400
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 500, 2, 50)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3125500
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 600, 2, 60)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3126600
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 700, 2, 70)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3127700
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 800, 2, 80)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3128800
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 900, 2, 90)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3129900
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_ZdlPvm(0x5865aab3ceb0, 40, 0x5865aab3c, 2)                                           = 0
+++ exited (status 0) +++

From demangler

std::ios_base::Init::Init()(0x58659f9b8151, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d30) = 0x72f4c90224b8
__cxa_atexit(0x72f4c92bf840, 0x58659f9b8151, 0x58659f9b8008, 0x72f4c942ada0)          = 0
operator new(unsigned long)(40, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d38)                             = 0x5865aab3ceb0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 100, 2, 10)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 0x7ffd6d84bac8100
)                       = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 200, 2, 20)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3122200
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 300, 2, 30)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3123300
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 400, 2, 40)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3124400
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 500, 2, 50)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3125500
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 600, 2, 60)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3126600
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 700, 2, 70)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3127700
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 800, 2, 80)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3128800
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 900, 2, 90)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3129900
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator delete(void*, unsigned long)(0x5865aab3ceb0, 40, 0x5865aab3c, 2)                                           = 0
    exited (status 0)    

Looks like a bunch of new and deletes are being called?

In some code I have written, a new FenwickTree is constructed from a vector ind that remains the same size every loop. The FenwickTree size is the same as the input vector. Will the compiler optimize not repeatedly at the start of the loop constructing the object and allocating memory, then destructing the object at the end of the loop? I am more familiar with C where memory management is explicit.

Example

#include <vector>
#include <iostream>

struct fenwick_tree
{
    size_t len; // 0-based len
    std::vector<int> t; // 1-based tree, indexes [1:len]

    fenwick_tree(std::vector<int> const &a) :
    len(a.size()), t(len + 1, 0) 
    {
        for (size_t i = 0; i < len; ++i)
            add_to(i, a[i]);
    }

    // 0-based input
    int sum_to(size_t r) const
    {
        int s = 0;
        for (++r; r > 0; r -= r & -r)
            s += t[r];
        return s;
    }

    // 0-based input
    void add_to(size_t i, int delta)
    {
        for (++i; i <= len; i += i & -i)
            t[i] += delta;
    }
};

int main()
{
    std::vector<int> ind(10, 10);
    for (int i = 1; i < 10; ++i)
    {
        ind.assign(10, 10*i);
        auto fen = fenwick_tree(ind);

        std::cout << fen.sum_to(9) << std::endl;
    }
}

This is the result of ltrace. I can see memset and flush, but I can't tell if

_ZNSt8ios_base4InitC1Ev(0x58659f9b8151, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d30) = 0x72f4c90224b8
__cxa_atexit(0x72f4c92bf840, 0x58659f9b8151, 0x58659f9b8008, 0x72f4c942ada0)          = 0
_Znwm(40, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d38)                             = 0x5865aab3ceb0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 100, 2, 10)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 0x7ffd6d84bac8100
)                       = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 200, 2, 20)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3122200
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 300, 2, 30)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3123300
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 400, 2, 40)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3124400
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 500, 2, 50)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3125500
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 600, 2, 60)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3126600
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 700, 2, 70)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3127700
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 800, 2, 80)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3128800
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_Znwm(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
_ZNSolsEi(0x58659f9b8040, 900, 2, 90)                                                 = 0x58659f9b8040
_ZNSo3putEc(0x58659f9b8040, 10, 0x72f4c9423370, 3129900
)                                 = 0x58659f9b8040
_ZNSo5flushEv(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
_ZdlPvm(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
_ZdlPvm(0x5865aab3ceb0, 40, 0x5865aab3c, 2)                                           = 0
+++ exited (status 0) +++

From demangler.com

std::ios_base::Init::Init()(0x58659f9b8151, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d30) = 0x72f4c90224b8
__cxa_atexit(0x72f4c92bf840, 0x58659f9b8151, 0x58659f9b8008, 0x72f4c942ada0)          = 0
operator new(unsigned long)(40, 0x7ffd6d84bd48, 0x7ffd6d84bd58, 0x58659f9b7d38)                             = 0x5865aab3ceb0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 100, 2, 10)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 0x7ffd6d84bac8100
)                       = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 200, 2, 20)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3122200
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 300, 2, 30)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3123300
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 400, 2, 40)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3124400
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 500, 2, 50)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3125500
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 600, 2, 60)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3126600
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 700, 2, 70)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3127700
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 800, 2, 80)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3128800
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator new(unsigned long)(44, 11, 0x5865aab3ced8, 0x5865aab3ced8)                                         = 0x5865aab3cee0
memset(0x5865aab3cee0, '\0', 44)                                                      = 0x5865aab3cee0
std::ostream::operator<<(int)(0x58659f9b8040, 900, 2, 90)                                                 = 0x58659f9b8040
std::ostream::put(char)(0x58659f9b8040, 10, 0x72f4c9423370, 3129900
)                                 = 0x58659f9b8040
std::ostream::flush()(0x58659f9b8040, 0x5865aab3cf20, 0x72f4c9423370, 0x72f4c8f14887)         = 0x58659f9b8040
operator delete(void*, unsigned long)(0x5865aab3cee0, 44, 0x72f4c9423370, 3072)                                     = 0
operator delete(void*, unsigned long)(0x5865aab3ceb0, 40, 0x5865aab3c, 2)                                           = 0
    exited (status 0)    

Looks like a bunch of new and deletes are being called?

Share Improve this question asked Jan 9 at 5:46 qwrqwr 10.8k6 gold badges68 silver badges114 bronze badges 13
  • 1 Try adding print statements to your class's constructor and destructor to see where and how often they get printed. – Jeremy Friesner Commented Jan 9 at 5:53
  • 2 auto fen is not an invariant of the loop (note the = will not result in an extra copy). And the content of your vector is changing (so also not invariant). I would add an explicit `operator=(const std::vector&) to your tree so you can reuse the instance. – Pepijn Kramer Commented Jan 9 at 6:10
  • 1 Haha, well this is not so much about C++ itself as what compilers can do with your code. Sleep well and when you are awake have a look at this : CppCon 2017: Matt Godbolt “What Has My Compiler Done for Me Lately? Unbolting the Compiler's Lid” – Pepijn Kramer Commented Jan 9 at 6:47
  • 1 @JeremyFriesner adding print statements adds side effects what will disable all possible optimization which compiler could do using As-If rule. So this would not prove anything. – Marek R Commented 2 days ago
  • 3 If you add print statements you guarantee that the compiler will not optimize out the constructor and destructor, because they will then have visible side effects. That doesn't tell you what the compiler would do in the absence of the print statements. – Pete Becker Commented 2 days ago
 |  Show 8 more comments

1 Answer 1

Reset to default 1

Compilers will optimize the stack allocation of sizeof(fen). That's so trivial that some compilers do this even in debug mode; it's not even an optimization step in their internal design.

Compilers will not optimize the allocation of the fenwick_tree::t. A vector's length can vary at runtime, and it's not part of sizeof(fenwick_tree). However, the standard library implementation typically does recycle memory. That recycling can happen inside operator new so that could still be visible in traces.

本文标签: cWill compilers optimize constructing a new object every loop if its size stays the sameStack Overflow