C string return from boost :: shared_ptr <string>

I wrap C ++ code in functions to make C ++ methods available in C.

C ++ API methods usually return objects boost::shared_ptr<T>. My exported function in C ++ is as follows:

extern "C" const char *Hazelcast_Map_get_int_string(
    Hazelcast_Client_t *hazelcastClient,
    const char *mapName,
    int key,
    char** errptr
) {
    IMap<int, string> map = hazelcastClient->client->getMap<int, string>(mapName);
    boost::shared_ptr<string> value = map.get(key);

    string *strValue = value.get();

    return strValue->c_str();
}

My client C code is as follows:

const char *stringValue = NULL;
stringValue = Hazelcast_Map_get_int_string(client, "int_string_map", 10, &err);

printf("got value from map %s\n", stringValue);

It still works, since it printfdisplays the correct value on stdout. However, checking the code with valgrind, it shows an invalid read error. Therefore, I believe that I am doing something wrong with passing pointers, but I cannot understand what the problem is.

Can I discard the strdupvalue boost::shared_ptr<string>or is this what I need to do?

Here's the error valgrind:

==20635== Invalid read of size 1
==20635==    at 0x10034C6BF: strlen (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==20635==    by 0x1006136E7: __vfprintf (in /usr/lib/system/libsystem_c.dylib)
==20635==    by 0x10063C35C: __v2printf (in /usr/lib/system/libsystem_c.dylib)
==20635==    by 0x10061201D: vfprintf_l (in /usr/lib/system/libsystem_c.dylib)
==20635==    by 0x10060FEB7: printf (in /usr/lib/system/libsystem_c.dylib)
==20635==    by 0x100001E6A: main (in ./hazelcastCClientTest)
==20635==  Address 0x100de9c41 is 1 bytes inside a block of size 24 free'd
==20635==    at 0x10034B2F7: free (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==20635==    by 0x1000068BF: void boost::checked_delete<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*) (in ./hazelcastCClientTest)
==20635==    by 0x100006888: boost::detail::sp_counted_impl_p<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::dispose() (in ./hazelcastCClientTest)
==20635==    by 0x1000054AD: boost::detail::sp_counted_base::release() (in ./hazelcastCClientTest)
==20635==    by 0x100005449: boost::detail::shared_count::~shared_count() (in ./hazelcastCClientTest)
==20635==    by 0x100005414: boost::detail::shared_count::~shared_count() (in ./hazelcastCClientTest)
==20635==    by 0x1000053F8: boost::shared_ptr<int>::~shared_ptr() (in ./hazelcastCClientTest)
==20635==    by 0x100004054: boost::shared_ptr<int>::~shared_ptr() (in ./hazelcastCClientTest)
==20635==    by 0x10000347F: Hazelcast_Map_get_int_string (in ./hazelcastCClientTest)
==20635==    by 0x100001E54: main (in ./hazelcastCClientTest)
==20635==  Block was alloc'd at
==20635==    at 0x10034AEBB: malloc (in /usr/local/Cellar/valgrind/3.11.0/lib/valgrind/vgpreload_memcheck-amd64-darwin.so)
==20635==    by 0x10038E7DD: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==20635==    by 0x1000B8C80: hazelcast::client::serialization::pimpl::DataInput::readUTF() (DataInput.cpp:147)
==20635==    by 0x1000E367F: std::__1::auto_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > hazelcast::client::serialization::pimpl::SerializationService::toObject<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(hazelcast::client::serialization::pimpl::Data const&) (SerializationService.cpp:590)
==20635==    by 0x10000659D: std::__1::auto_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > hazelcast::client::proxy::ProxyImpl::toObject<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(hazelcast::client::serialization::pimpl::Data const&) (in ./hazelcastCClientTest)
==20635==    by 0x100006413: std::__1::auto_ptr<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > > hazelcast::client::proxy::ProxyImpl::toObject<std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >(std::__1::auto_ptr<hazelcast::client::serialization::pimpl::Data>) (in ./hazelcastCClientTest)
==20635==    by 0x10000484B: hazelcast::client::IMap<int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > >::get(int const&) (in ./hazelcastCClientTest)
==20635==    by 0x10000338F: Hazelcast_Map_get_int_string (in ./hazelcastCClientTest)
==20635==    by 0x100001E54: main (in ./hazelcastCClientTest)

EDIT: what is the desired effect?. , C - , , , , NULL .

EDIT 2: , , , Ayende https://ayende.com/blog/161281/robs-sprint-the-cost-of-getting-data-from-leveldb , , leveldb C/#.

, , .

+4
1

, (, C-API), . () :

extern "C" int Hazelcast_Map_get_int_string(
    Hazelcast_Client_t *hazelcastClient,
    const char *mapName,
    int key,
    char **value,
    char** errptr
) {
    assert(hazelcastClient != NULL);
    assert(hazelcastClient->client != NULL);

    assert(mapName != NULL);

    assert(value != NULL);

    try {
        auto map = hazelcastClient->client->getMap<int, string>(mapName);
        boost::shared_ptr<string> sharedPtr = map.get(key);

        string *ptr = sharedPtr.get();

        if (ptr == NULL) {
            return 0;
        }

        *value = strdup(ptr->c_str());
        return 0;
    } catch(const std::runtime_error& re) {
        saveMessageInErrPtr(errptr, re.what());
    } catch(const std::exception& ex) {
        saveMessageInErrPtr(errptr, ex.what());
    } catch(...) {
        saveUnknownErrorOccurredMessageInErrPtr(errptr);
    }

    return 1;
}

, /, errptr.

:

char *stringValue = NULL;

if (Hazelcast_Map_get_int_string(client, "int_string_map", 10, &stringValue, &err) != 0) {
    printf("ERR Map get failed: %s\n", err);
    Hazelcast_free(err); err = NULL;
} else {
    printf("got value from map %s\n", stringValue);
    free(stringValue);
}

, , .

0

All Articles