Script fails with error "std::bad_alloc" or segmentation fault

  c++, segmentation-fault

In the below script, when I change the value of MAX_TEXTURE_SIZE above (24*1024) it fails with an error

terminate called after throwing an instance of ‘std::bad_alloc’
what(): std::bad_alloc Aborted (core dumped)

And, if I change value of MAX_TEXTURE_SIZE to (1024*124) it fails with an error:

Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Received signal SIGSEGV
(segmentation fault) Received signal SIGSEGV (segmentation fault)
Received signal SIGSEGV (segmentation fault) Obtained Obtained 11
stack frames: 0x5604920520a4 0x7fba4f8cc040 0x560491f9d9a1
0x560491f9f893Received signal SIGSEGV (segmentation fault)Obtained 11
stack frames: 0x5604920520a4 Obtained 11 stack frames: 0x5604920520a4
0x7fba4f8cc040Obtained Obtained 0xb0x560491f4076cObtained 11Obtained
11 stack frames: stack frames: Obtained 0x5604920520a4 0x7fba4f8cc040
0x560491f9d9a1Obtained 0xb stack frames:Obtained Obtained
0x7fba4f8cc04011Received signal SIGSEGV (segmentation fault)Obtained
stack frames:Obtained Obtained Obtained Obtained 0xb Obtained Obtained
0x5604920520a4Obtained Obtained Obtained 0xb stack
frames:0x560491f9f8930xbObtained Obtained stack frames: Obtained
stack frames: 0x5604920520a40xb0x5604920520a4 stack frames:0xb0xb0xb
stack frames: 0xb0xb0xb stack frames: 0x5604920520a4 stack
frames:0xb0x560491f9d9a10xb stack frames: 0xb0x5604920520a4 stack
frames: 0x7fba4f8cc040Obtained 0xb stack frames: 0x5604920520a4
0x7fba4f8cc040 Received signal SIGSEGV (segmentation fault)Received
signal SIGSEGV (segmentation fault)

#########################Code#########################################################

#include <set>
#include <list>
#include <iostream>
#include <fstream>
#include <stdint.h>
#include <util/timer.h>
#include <mve/image_tools.h>

#include "defines.h"
#include "settings.h"
#include "histogram.h"
#include "texture_patch.h"
#include "texture_atlas.h"

#define MAX_TEXTURE_SIZE (24 * 1024)
#define PREF_TEXTURE_SIZE (4 * 1024)
#define MIN_TEXTURE_SIZE (256)

TEX_NAMESPACE_BEGIN

unsigned int
calculate_texture_size(std::list<TexturePatch::ConstPtr> const & texture_patches) {
    unsigned int size = MAX_TEXTURE_SIZE;

    while (true) {
        unsigned int total_area = 0;
        unsigned int max_width = 0;
        unsigned int max_height = 0;
        unsigned int padding = size >> 7;

        for (TexturePatch::ConstPtr texture_patch : texture_patches) {
            unsigned int width = texture_patch->get_width() + 2 * padding;
            unsigned int height = texture_patch->get_height() + 2 * padding;

            max_width = std::max(max_width, width);
            max_height = std::max(max_height, height);

            unsigned int area = width * height;
            unsigned int waste = area - texture_patch->get_size();

            /* Only consider patches where the information dominates padding. */
            if (static_cast<double>(waste) / texture_patch->get_size() > 1.0) {
                /* Since the patches are sorted by size we can assume that only
                 * few further patches will contribute to the size and break. */
                break;
            }

            total_area += area;
        }

        assert(max_width < MAX_TEXTURE_SIZE);
        assert(max_height < MAX_TEXTURE_SIZE);
        if (size > PREF_TEXTURE_SIZE &&
            max_width < PREF_TEXTURE_SIZE &&
            max_height < PREF_TEXTURE_SIZE &&
            total_area / (PREF_TEXTURE_SIZE * PREF_TEXTURE_SIZE) < 8) {
            size = PREF_TEXTURE_SIZE;
            continue;
        }

        if (size <= MIN_TEXTURE_SIZE) {
            return MIN_TEXTURE_SIZE;
        }

        if (max_height < size / 2 && max_width < size / 2 &&
            static_cast<double>(total_area) / (size * size) < 0.2) {
            size = size / 2;
            continue;
        }

        return size;
    }
}

bool comp(TexturePatch::ConstPtr first, TexturePatch::ConstPtr second) {
    return first->get_size() > second->get_size();
}

void
generate_texture_atlases(std::vector<TexturePatch::Ptr> * orig_texture_patches,
    Settings const & settings, std::vector<TextureAtlas::Ptr> * texture_atlases) {

    std::list<TexturePatch::ConstPtr> texture_patches;
    while (!orig_texture_patches->empty()) {
        TexturePatch::Ptr texture_patch = orig_texture_patches->back();
        orig_texture_patches->pop_back();

        if (settings.tone_mapping != TONE_MAPPING_NONE) {
            mve::image::gamma_correct(texture_patch->get_image(), 1.0f / 2.2f);
        }

        texture_patches.push_back(texture_patch);
    }

    std::cout << "tSorting texture patches... " << std::flush;
    /* Improve the bin-packing algorithm efficiency by sorting texture patches
     * in descending order of size. */
    texture_patches.sort(comp);
    std::cout << texture_patches.size() << "n";
    std::cout << "done." << std::endl;
    std::cout << ".........." << "n";
    std::size_t const total_num_patches = texture_patches.size();
    std::cout << texture_patches.size() << "n";
    std::size_t remaining_patches = texture_patches.size();
    std::cout << texture_patches.size() << "n";
    std::ofstream tty("/dev/tty", std::ios_base::out);
    std::cout << texture_patches.size() << "n";

    #pragma omp parallel
    {
    #pragma omp single
    {

    while (!texture_patches.empty()) {
        unsigned int texture_size = calculate_texture_size(texture_patches);

        texture_atlases->push_back(TextureAtlas::create(texture_size));
        TextureAtlas::Ptr texture_atlas = texture_atlases->back();

        /* Try to insert each of the texture patches into the texture atlas. */
        std::list<TexturePatch::ConstPtr>::iterator it = texture_patches.begin();
        for (; it != texture_patches.end();) {
            std::size_t done_patches = total_num_patches - remaining_patches;
            int precent = static_cast<float>(done_patches)
                / total_num_patches * 100.0f;
            if (total_num_patches > 100
                && done_patches % (total_num_patches / 100) == 0) {

                tty << "rtWorking on atlas " << texture_atlases->size() << " "
                 << precent << "%... " << std::flush;
            }

            if (texture_atlas->insert(*it)) {
                it = texture_patches.erase(it);
                remaining_patches -= 1;
            } else {
                ++it;
            }
        }

        #pragma omp task
        texture_atlas->finalize();
    }

    std::cout << "rtWorking on atlas " << texture_atlases->size()
        << " 100%... done." << std::endl;
    util::WallTimer timer;
    std::cout << "tFinalizing texture atlases... " << std::flush;
    #pragma omp taskwait
    std::cout << "done. (Took: " << timer.get_elapsed_sec() << "s)" << std::endl;

    /* End of single region */
    }
    /* End of parallel region. */
    }
}

TEX_NAMESPACE_END

Source: Windows Questions C++

LEAVE A COMMENT