Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7768949
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T16:03:05+00:00 2026-06-01T16:03:05+00:00

Currently I have implemented a reference-counting cache of the values of the map like

  • 0

Currently I have implemented a reference-counting cache of the values of the map like so:

//filename or name of bitmap, reference count, memory location...
std::map<std::string, std::pair<long, BITMAP*> > _cache;

Is using a std::multimap a better choice?

//filename or name of bitmap, memory location...
std::multimap<std::string, BITMAP*> _cache;

Or just a different way of doing it?

— EDIT —

Here’s the specific class for clarity of my intentions It is intended to be a private class that is strictly utility to the rest of the code that the user never sees. To them, they are just creating a Sprite. NOTE: The BITMAP struct is considered private and the only way to create/destroy/modify one is through one of the many functions in the 3rd-party C library that REQUIRE the use of raw pointers.

BitmapCache.h

#ifndef A2DE_CBITMAPCACHE_H
#define A2DE_CBITMAPCACHE_H

#include "../a2de_vals.h"
#include <allegro/file.h>
#include <allegro/gfx.h>
#include <allegro/draw.h>
#include <allegro/datafile.h>
#include <allegro/color.h>

#include <map>
#include <utility>
#include <string>

struct BITMAP;

_A2DE_BEGIN

class BitmapCache {
public:
    static BITMAP* GetBitmap(std::string filename);
    static BITMAP* StoreBitmap(std::string name, BITMAP* bmp);
    static BITMAP* RetrieveBitmap(std::string name);
    static std::string GetBitmapName(BITMAP* file);
    static void RemoveBitmap(std::string name);

protected:
private:
    static std::map<std::string, std::pair<long, BITMAP*> > _cache;
    static void CleanCache();

};

_A2DE_END

#endif

BitmapCache.cpp

#include "CBitmapCache.h"

#include <algorithm>
#include <map>

_A2DE_BEGIN

//filename or name of bitmap, reference count, memory location...
typedef std::map<std::string, std::pair<long, BITMAP*> > MapStrBmp;
typedef MapStrBmp::iterator MapStrBmpIter;

MapStrBmp BitmapCache::_cache;

BITMAP* BitmapCache::GetBitmap(std::string filename) {
    //Return NULL if a bad filename was passed.
    if(filename.empty()) return NULL;
    if(exists(filename.c_str()) == false) return NULL;

    //Reduce incorrect results by forcing slash equality.
    filename = fix_filename_slashes(&filename[0]);

    //Clean the cache if it's dirty.
    CleanCache();

    //Search for requested BITMAP.
    MapStrBmpIter _iter = _cache.find(filename);

    //If found, return it.
    if(_iter != _cache.end()) {
        _iter->second.first++;
        return _iter->second.second;
    }

    //Otherwise, create it, store it, then return it.
    BITMAP* result = load_bmp(filename.c_str(), NULL);
    if(result == NULL) return NULL;
    _cache.insert(std::make_pair(filename, std::make_pair(static_cast<long>(1), result)));
    return result;
}

BITMAP* BitmapCache::StoreBitmap(std::string name, BITMAP* bmp) {
    if(name.empty() || bmp == NULL) return NULL;

    CleanCache();
    name = fix_filename_slashes(&name[0]);
    MapStrBmpIter _iter = _cache.find(name);
    if(_iter != _cache.end()) {
        _iter->second.first++;
        return _iter->second.second;
    }

    _cache.insert(std::make_pair(name, std::make_pair(static_cast<long>(1), bmp)));
    return bmp;
}
BITMAP* BitmapCache::RetrieveBitmap(std::string name) {
    if(name.empty()) return NULL;

    name = fix_filename_slashes(&name[0]);
    MapStrBmpIter _iter = _cache.find(name);
    if(_iter != _cache.end()) {
        _iter->second.first++;
        return _iter->second.second;
    }
    return NULL;
}

void BitmapCache::RemoveBitmap(std::string name) {
    if(name.empty()) return;

    name = fix_filename_slashes(&name[0]);
    MapStrBmpIter _iter = _cache.find(name);

    if(_iter != _cache.end()) {
        _iter->second.first--;
        CleanCache();
    }
}

std::string BitmapCache::GetBitmapName(BITMAP* file) {
    if(file == NULL) return std::string("");

    CleanCache();
    MapStrBmpIter b = _cache.begin();
    MapStrBmpIter e = _cache.end();
    for(MapStrBmpIter _iter = b; _iter != e; ++_iter) {
        if(_iter->second.second != file) continue;
        return _iter->first;
    }
    return std::string("");
}

void BitmapCache::CleanCache() {

    //Clean the cache of any bitmaps that are no longer referenced.
    MapStrBmpIter b = _cache.begin();
    MapStrBmpIter e = _cache.end();
    for(MapStrBmpIter _iter = b; _iter != e; /* DO NOTHING */ ) {
        if(_iter->second.first > 0) {
            ++_iter;
            continue;
        }
        destroy_bitmap(_iter->second.second);
        _iter->second.second = NULL;
        _cache.erase(_iter++);
    }
}

_A2DE_END
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T16:03:06+00:00Added an answer on June 1, 2026 at 4:03 pm

    Well, it turns out I can’t use STL smart pointers with what I am trying to do. After re-working the above code to use smart pointers the program kept crashing on close. It turns out that the allegro 4.2 library API specifically states that attempting to call allegro methods (specifically ones that deal with bitmaps…) after allegro has been deinitialized will crash the program. Smart pointers only destroy themselves (and try to call their contained pointer’s deleter methods) after they’ve run out of scope…after the program has ended and allegro has been deinitialized, which in turn crashes the program.

    So for now, the current solution of rolling my own implementation of reference counting is the work-around.

    Thanks for the advice and the help anyway.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I currently have implemented an overlay item that shows an icon for Geo-point on
Currently I have implemented a Javascript Ajax search where if user types a city
Backgroup: We are looking at SAS BI Dashboard. We have currently implemented almost all
I have implemented a table view with multiple threads. Currently when a user taps
I have implemented a UISearchDisplayController that allows users to search a table. Currently the
I am currently writing a Java compiler and have implemented section 15.12.2.7. of the
Noticing how badly implemented is reference counting in current Objective-C (see here and here
I have implemented Twitter OAuth in my web application, the web application currently fetches
I have implemented correctly bump's api, and added this code: - (void) configureBump {
At my current job I have implemented the Repository/UoW patterns on top of EntityFramework

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.