1
votes

For one of my projects, I need to use shared_ptr to struct tm as the key to a STL map. Below is my testing code. In the for loop, there are two ways to create a shared_ptr: 1) TmSPtr tm_ptr = std::make_shared(* tminfo); 2) TmSPtr tm_ptr(tminfo). Both can compile; however during run-time, the 2nd method throws an error: "* Error in `./a.out': free(): invalid pointer: 0x00007f52e0222de0 * Aborted (core dumped)", indicating that it tries to free memory that does not exist. I am still quite new to smart pointers, so hopefully can get some insight from the forum.

Apologies that I may have included more headers than needed

#include <iostream>
#include <map>
#include <algorithm>
#include <iterator>
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>

using namespace std;

typedef std::shared_ptr<struct tm> TmSPtr;

int main()
{
    cout << "\nTesting a map where key is a smart ptr to struct tm:\n";
    map<TmSPtr, int> price_series;

    for (int i = 0; i < 5; ++i) {
        time_t now;
        time(&now);
        struct tm * tminfo = localtime(&now);
        printf("Current local time and date: %s", asctime(tminfo));

        TmSPtr tm_ptr = std::make_shared<struct tm>(*tminfo); // TmSPtr tm_ptr(tminfo); would fail in run time

        price_series.insert(std::pair<TmSPtr, int>(tm_ptr, i));

        usleep(1000000); // 1 sec
    }
    return 0;
}
2
Why are you using a shared pointer as your key instead the type itself? - Qartar
I use price_series as variable name in the map. Actually I could have 1000 price series, all of which share the same time stamps. I think using struct tm is too expensive, isn't it. There is really only 1 series of time stamps. Hopefully my explanation makes sense. - tgh123
Use mktime() and store a time_t (integer) instead. Using pointers as keys is a bad idea, using shared_ptrs as keys is a terrible idea. - Qartar

2 Answers

4
votes

localtime(3) says: "The return value points to a statically allocated struct ...". That means the memory is not on the heap, so should not be de-allocated.

Your first method works because it copies the structure.

0
votes

Shared pointers delete their object when all references to that object go out of scope. This means the underlying object needs to be allocated using new. But your second method is pointing to a statically allocated variable - which is destroyed automatically. The first method creates a copy of the object and so is safe.