Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

const inline std::map in header causes heap corruption at exit

Tags:

I want to have const std::map in header as a global constant that will be used in other cpp-s. So I declared it as:

// header.h
const inline std::map<int, int> GlobalMap = { {1, 2}, {3, 4} };

However, if I include this header in multiple cpp-s, heap corruption happens at exit time because multiple destructors are run for the same memory address.

I've always assumed that inline const is a silver bullet for global non-literal constants. I've declared global std::string-s as const inline and it worked just fine.

So my questions are:

  1. Why is this intended to happen? Doesn't it make const inline very error prone?
  2. How do I properly declare global const std::map in C++17? And how can I ensure that only one global object would be created?

EDIT: I can reproduce it on the following project in Visual Studio 2017 (/std:c++17, Debug x86)

file_1.h:

#pragma once
#include <map>

const inline std::map<int, double> GlobalMap = {{1, 1.5}, {2, 2.5}, {3, 3.5}};

void f1();

file_1.cpp:

#include "file_1.h"

void f1()
{
    (void)GlobalMap;
}

main.cpp:

#include "file_1.h"

int main()
{
    f1();
    return 0;
}
like image 802
Victor Avatar asked Sep 08 '21 09:09

Victor


1 Answers

This looks like a Visual Studio bug: https://developercommunity.visualstudio.com/t/static-inline-variable-gets-destroyed-multiple-tim/297876

At the time of posting, the bug has status "Closed - Lower Priority", i.e. it is not fixed.

From the comment of the Microsoft representative:

If you still face this issue in our latest version, please report it as a new problem.

So I'd suggest filing a new problem with a repro-case.

like image 179
Mikhail Avatar answered Nov 15 '22 07:11

Mikhail