Friday, September 20, 2019

Unique Pointer (Smart Pointer)

The following example shows how to use unique_ptr which semantically 'moves' the data during assignment:


#include <iostream>
#include <memory>


using namespace std;


class MyClass
{
public:

#if COMPILE_ERROR
    MyClass
    (
        std::unique_ptr<int> const &  pOpt = std::unique_ptr<int>(nullptr) 
    ) : m_ptr(std::move(pOpt))
    {
    }
#else
    explicit MyClass
    ( 
        std::unique_ptr<int> pOpt = std::unique_ptr<int>(nullptr)
    ) : m_ptr(std::move(pOpt))
    {
        std::cout << __FUNCTION__ << "() : m_ptr=" << m_ptr.get() << std::endl;
    }

    MyClass() = delete;

#endif
    friend ostream& operator<<(ostream& os, const MyClass& c);

private:
    std::unique_ptr<int>  m_ptr;
};


template<typename T>
std::unique_ptr<T>& pass_through(std::unique_ptr<T>& p)
{
    if (p != nullptr)
        std::cout << *p << std::endl;
    else
        std::cout << "nullptr" << std::endl;
    return p;
}


ostream& operator<<(ostream& os, const MyClass& c)
{
    if (c.m_ptr != nullptr)
        return os << __FUNCTION__ << "(): " <<  *c.m_ptr;
    else
        return os << __FUNCTION__ << "(): nullptr";
}


int main()
{
    std::unique_ptr<int> pInt(new int(15));

    MyClass data();
    MyClass data2(std::move(pInt));

    pass_through(pInt);
    
    std::cout << "data = " << data << std::endl;
    std::cout << "data2 = " << data2 << std::endl;
}


MyClass() : m_ptr=0x7430d0

nullptr

data = 1

data2 = operator<<(): 15




Wednesday, March 13, 2019

Callback via C++ template

The following code would make a callback via template:


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
#include <iostream>


template <typename F>
void call(F func)
{
    func();
}


void print()
{
    std::cout << __FUNCTION__ << "()" << std::endl;
}

int main()
{
    call(print);
}

Sunday, March 10, 2019

Debugging Issues related to GLib

Got this problem when running my compiled wxformbuilder:


***MEMORY-ERROR***: wxformbuilder[19377]: GSlice: assertion failed: aligned_memory == (gpointer) addr
Aborted (core dumped)

The workaround is to embed G_SLICE=always-malloc when invoking the command-line, e.g:

G_SLICE=always-malloc ./wxformbuilder 

According to the GLib documentation:

always-malloc:This will cause all slices allocated through g_slice_alloc() and released by g_slice_free1() to be actually allocated via direct calls to g_malloc() and g_free(). This is most useful for memory checkers and similar programs that use Boehm GC alike algorithms to produce more accurate results. It can also be in conjunction with debugging features of the system's malloc() implementation such as glibc's MALLOC_CHECK_=2 to debug erroneous slice allocation code, although debug-blocks is usually a better suited debugging tool.

To debug the issue, valgrind is our friend in this case.

For example, when running it with valgrind it shows a lot of memory leaks (apparently some issues in wxWidgets):



valgrind ./wxformbuilder

==18887== Memcheck, a memory error detector

==18887== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.

==18887== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info

==18887== Command: ./wxformbuilder

==18887==

==18887== Invalid free() / delete / delete[] / realloc()
==18887== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0x6EAE3D0: wxLocale::GetSystemEncodingName() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAEA2A: wxLocale::GetSystemEncoding() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F06C18: wxCSConv::SetEncoding(wxFontEncoding) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D2E3: wxCSConv::wxCSConv(wxFontEncoding) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D398: wxGet_wxConvLocalPtr() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6DD07CE: _GLOBAL__sub_I_strconv.cpp (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x4010732: call_init (dl-init.c:72)

==18887== by 0x4010732: _dl_init (dl-init.c:119)

==18887== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

==18887== Address 0x4029fe0 is in a rwx anonymous segment

==18887==

==18887== Invalid read of size 16

==18887== at 0x7E8798D: __wcsnlen_sse4_1 (strlen.S:117)

==18887== by 0x7E74EC1: wcsrtombs (wcsrtombs.c:104)

==18887== by 0x6F8B13F: wxWC2MB(char*, wchar_t const*, unsigned long) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F07CD5: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0C2F9: wxCSConv::DoCreate() const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D2EB: wxCSConv::wxCSConv(wxFontEncoding) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D398: wxGet_wxConvLocalPtr() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6DD07CE: _GLOBAL__sub_I_strconv.cpp (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x4010732: call_init (dl-init.c:72)

==18887== by 0x4010732: _dl_init (dl-init.c:119)

==18887== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

==18887== Address 0x14d47b30 is 8 bytes after a block of size 24 alloc'd

==18887== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0x6F07DB7: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0C2F9: wxCSConv::DoCreate() const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D2EB: wxCSConv::wxCSConv(wxFontEncoding) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D398: wxGet_wxConvLocalPtr() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6DD07CE: _GLOBAL__sub_I_strconv.cpp (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x4010732: call_init (dl-init.c:72)

==18887== by 0x4010732: _dl_init (dl-init.c:119)

==18887== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

==18887==

==18887== Invalid read of size 16

==18887== at 0x7E87992: __wcsnlen_sse4_1 (strlen.S:117)

==18887== by 0x7E74EC1: wcsrtombs (wcsrtombs.c:104)

==18887== by 0x6F8B13F: wxWC2MB(char*, wchar_t const*, unsigned long) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F07CD5: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0C2F9: wxCSConv::DoCreate() const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D2EB: wxCSConv::wxCSConv(wxFontEncoding) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D398: wxGet_wxConvLocalPtr() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6DD07CE: _GLOBAL__sub_I_strconv.cpp (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x4010732: call_init (dl-init.c:72)

==18887== by 0x4010732: _dl_init (dl-init.c:119)

==18887== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

==18887== Address 0x14d47b40 is 16 bytes after a block of size 32 in arena "client"

==18887==

==18887== Conditional jump or move depends on uninitialised value(s)

==18887== at 0x7E87A61: __wcsnlen_sse4_1 (strlen.S:161)

==18887== by 0x7E74EC1: wcsrtombs (wcsrtombs.c:104)

==18887== by 0x6F8B13F: wxWC2MB(char*, wchar_t const*, unsigned long) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F07CD5: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0C2F9: wxCSConv::DoCreate() const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D2EB: wxCSConv::wxCSConv(wxFontEncoding) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F0D398: wxGet_wxConvLocalPtr() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6DD07CE: _GLOBAL__sub_I_strconv.cpp (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x4010732: call_init (dl-init.c:72)

==18887== by 0x4010732: _dl_init (dl-init.c:119)

==18887== by 0x40010C9: ??? (in /lib/x86_64-linux-gnu/ld-2.27.so)

==18887==

==18887== Invalid free() / delete / delete[] / realloc()

==18887== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0x6EAE3D0: wxLocale::GetSystemEncodingName() (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x629CE5E: wxApp::Initialize(int&, wchar_t**) (in /usr/local/lib/libwx_gtk3u_core-3.1.so.3.0.0)

==18887== by 0x6EABB9C: wxEntryStart(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5A9: wxInitialize(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5FA: wxEntry(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x1E8D57: main (maingui.cpp:83)

==18887== Address 0x4029fc0 is in a rwx anonymous segment

==18887==

==18887== Invalid read of size 16

==18887== at 0x7E87AC2: __wcsnlen_sse4_1 (strlen.S:194)

==18887== by 0x7E74EC1: wcsrtombs (wcsrtombs.c:104)

==18887== by 0x6F8B13F: wxWC2MB(char*, wchar_t const*, unsigned long) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F07CD5: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6E763C4: wxString::AsCharBuf(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x7016906: wxSetEnv(wxString const&, wxString const&) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x629D359: wxApp::Initialize(int&, wchar_t**) (in /usr/local/lib/libwx_gtk3u_core-3.1.so.3.0.0)

==18887== by 0x6EABB9C: wxEntryStart(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5A9: wxInitialize(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5FA: wxEntry(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x1E8D57: main (maingui.cpp:83)

==18887== Address 0x14e00f20 is 0 bytes after a block of size 80 alloc'd

==18887== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0x6F07DB7: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6E763C4: wxString::AsCharBuf(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x7016906: wxSetEnv(wxString const&, wxString const&) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x629D359: wxApp::Initialize(int&, wchar_t**) (in /usr/local/lib/libwx_gtk3u_core-3.1.so.3.0.0)

==18887== by 0x6EABB9C: wxEntryStart(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5A9: wxInitialize(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5FA: wxEntry(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x1E8D57: main (maingui.cpp:83)

==18887==

==18887== Invalid read of size 16

==18887== at 0x7E87AC7: __wcsnlen_sse4_1 (strlen.S:194)

==18887== by 0x7E74EC1: wcsrtombs (wcsrtombs.c:104)

==18887== by 0x6F8B13F: wxWC2MB(char*, wchar_t const*, unsigned long) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F07CD5: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6E763C4: wxString::AsCharBuf(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x7016906: wxSetEnv(wxString const&, wxString const&) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x629D359: wxApp::Initialize(int&, wchar_t**) (in /usr/local/lib/libwx_gtk3u_core-3.1.so.3.0.0)

==18887== by 0x6EABB9C: wxEntryStart(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5A9: wxInitialize(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5FA: wxEntry(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x1E8D57: main (maingui.cpp:83)

==18887== Address 0x14e00f30 is 16 bytes after a block of size 80 alloc'd

==18887== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0x6F07DB7: wxMBConv::FromWChar(char*, unsigned long, wchar_t const*, unsigned long) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6F14F78: wxString::AsChar(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6E763C4: wxString::AsCharBuf(wxMBConv const&) const (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x7016906: wxSetEnv(wxString const&, wxString const&) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x629D359: wxApp::Initialize(int&, wchar_t**) (in /usr/local/lib/libwx_gtk3u_core-3.1.so.3.0.0)

==18887== by 0x6EABB9C: wxEntryStart(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5A9: wxInitialize(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x6EAC5FA: wxEntry(int&, wchar_t**) (in /usr/local/lib/libwx_baseu-3.1.so.3.0.0)

==18887== by 0x1E8D57: main (maingui.cpp:83)

==18887==

==18887== Invalid free() / delete / delete[] / realloc()

==18887== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0xA95DAFB: _XFreeDisplayStructure (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)

==18887== by 0xA94AE7E: XCloseDisplay (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)

==18887== by 0x12331FC8: atspi_get_a11y_bus (in /usr/lib/x86_64-linux-gnu/libatspi.so.0.0.1)

==18887== by 0xD2DEE89: atk_bridge_adaptor_init (in /usr/lib/x86_64-linux-gnu/libatk-bridge-2.0.so.0.0.0)

==18887== by 0x85D3B03: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2200.30)

==18887== by 0x8774498: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2200.30)

==18887== by 0x915410C: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x916705D: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x916F714: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x917012E: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x91585C3: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== Address 0x4029f00 is in a rwx anonymous segment

==18887==

==18887== Invalid free() / delete / delete[] / realloc()

==18887== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)

==18887== by 0xA95DD09: _XFreeDisplayStructure (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)

==18887== by 0xA94AE7E: XCloseDisplay (in /usr/lib/x86_64-linux-gnu/libX11.so.6.3.0)

==18887== by 0x12331FC8: atspi_get_a11y_bus (in /usr/lib/x86_64-linux-gnu/libatspi.so.0.0.1)

==18887== by 0xD2DEE89: atk_bridge_adaptor_init (in /usr/lib/x86_64-linux-gnu/libatk-bridge-2.0.so.0.0.0)

==18887== by 0x85D3B03: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2200.30)

==18887== by 0x8774498: ??? (in /usr/lib/x86_64-linux-gnu/libgtk-3.so.0.2200.30)

==18887== by 0x915410C: g_closure_invoke (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x916705D: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x916F714: g_signal_emit_valist (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x917012E: g_signal_emit (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== by 0x91585C3: ??? (in /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0.5600.3)

==18887== Address 0x4029f10 is in a rwx anonymous segment
...
...

==20545== More than 1000 different errors detected.  I'm not reporting any more.
==20545== Final error counts will be inaccurate.  Go fix your program!
==20545== Rerun with --error-limit=no to disable this cutoff.  Note
==20545== that errors may occur in your program without prior warning from
==20545== Valgrind, because errors are no longer being displayed.
==20545== 

Debugging with GDB gives:

$ gdb /usr/local/bin/wxformbuilder
GNU gdb (Ubuntu 8.1-0ubuntu3) 8.1.0.20180409-git
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/local/bin/wxformbuilder...done.
(gdb) go
Command requires an argument.
(gdb) run
Starting program: /usr/local/bin/wxformbuilder
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
***MEMORY-ERROR***: wxformbuilder[22214]: GSlice: assertion failed: aligned_memory == (gpointer) addr
Program received signal SIGABRT, Aborted.
__GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
(gdb) bt
#0  0x00007ffff4aa7e97 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1  0x00007ffff4aa9801 in __GI_abort () at abort.c:79
#2  0x00007ffff23496b4 in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#3  0x00007ffff234a0db in  () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#4  0x00007ffff234ad1e in g_slice_alloc () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#5  0x00007ffff234ad99 in g_slice_alloc0 () at /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
#6  0x00007ffff38ad925 in g_type_create_instance () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#7  0x00007ffff388e748 in  () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#8  0x00007ffff388fee5 in g_object_new_with_properties () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#9  0x00007ffff3890961 in g_object_new () at /usr/lib/x86_64-linux-gnu/libgobject-2.0.so.0
#10 0x00007ffff3b3dbda in  () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#11 0x00007ffff3b2de3d in  () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#12 0x00007ffff3b02d5d in gdk_display_manager_open_display () at /usr/lib/x86_64-linux-gnu/libgdk-3.so.0
#13 0x00007ffff3ff267a in gtk_init_check () at /usr/lib/x86_64-linux-gnu/libgtk-3.so.0
#14 0x00007ffff64324ae in wxApp::Initialize(int&, wchar_t**) () at /usr/local/lib/libwx_gtk3u_core-3.1.so.3
#15 0x00007ffff5a53b9d in wxEntryStart(int&, wchar_t**) () at /usr/local/lib/libwx_baseu-3.1.so.3
#16 0x00007ffff5a545aa in wxInitialize(int&, wchar_t**) () at /usr/local/lib/libwx_baseu-3.1.so.3
#17 0x00007ffff5a545fb in wxEntry(int&, wchar_t**) () at /usr/local/lib/libwx_baseu-3.1.so.3
#18 0x0000555555634d58 in main(int, char**) (argc=1, argv=0x7fffffffded8) at ../src/maingui.cpp:83

Tuesday, January 15, 2019

Fast String Reversal

Prime Number checking of Fibonacci sequence Number

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
// (c) 2019, Lutfi Shihab


#include <iostream>
#include <vector>
// todo
template <typename T>
class Matrix
{
public:
    Matrix(int rows, int cols) : m_rows(rows), m_cols(cols) {}
    
private:
    int m_rows;
    int m_cols;
};

 
/* function that returns nth Fibonacci number */
template <typename T>
class Fibonacci
{
public:
    Fibonacci(T n) { m_fibNum = fib(n); }
    operator T() const { return m_fibNum; }
    operator int() const { return m_fibNum; }
    
    friend std::ostream& operator<<(std::ostream& os, Fibonacci<T>&  f)
    {
        return os << f.m_fibNum;
    }
    
    Fibonacci<T> operator+=(int k) { return m_fibNum += k; }
    Fibonacci<T> operator %(int k) { return m_fibNum % k; }
    Fibonacci<T> operator /(int k) { return m_fibNum / k; }
    bool         operator<=(int k) { return m_fibNum < k; }
    bool         operator >(int k) { return m_fibNum > k; }
    bool         operator==(int k) { return m_fibNum == k; }

 private:
    void multiply(T F[2][2], T M[2][2])
    {
        T x =  F[0][0]*M[0][0] + F[0][1]*M[1][0]; 
        T y =  F[0][0]*M[0][1] + F[0][1]*M[1][1]; 
        T z =  F[1][0]*M[0][0] + F[1][1]*M[1][0]; 
        T w =  F[1][0]*M[0][1] + F[1][1]*M[1][1]; 
  
        F[0][0] = x; 
        F[0][1] = y; 
        F[1][0] = z; 
        F[1][1] = w;
    }

    /* Optimized version of power() */
    void power(T F[2][2], T n)
    {

        if( n == 0 || n == 1) 
            return; 
        T M[2][2] = {{1,1},{1,0}}; 
  
        this->power(F, n/2); 
        multiply(F, F); 
  
        if (n%2 != 0) 
        multiply(F, M); 
    }

    T fib(T n) 
    { 
        T F[2][2] = {{1,1},{1,0}}; 
        if (n == 0) 
        {
            return 0;
        }
        power(F, n-1); 
  
        return F[0][0]; 
    } 


    T       m_fibNum;
};

  

// Returns n! (the factorial of n)
int Factorial(int n) 
{
    int result = 1;
    for (int i = 1; i <= n; i++) 
    {
        result *= i;
    }

    return result;
}


// Returns true if n is a prime number
template<typename T>
bool IsPrime(T n) 
{
  // Trivial case 1: small numbers
    if (n <= 1) return false;

    // Trivial case 2: even numbers
    if (n % 2 == 0) return n == 2;

    // Now, we have that n is odd and n >= 3.

    // Try to divide n by every odd number i, starting from 3
    for (T i = 3; ; i += 2) 
    {
        // We only have to try i up to the squre root of n
        if (i > n/i) break;

        // Now, we have i <= n/i < n.
        // If n is divisible by i, n is not prime.
        if (n % i == 0) return false;
    }

    // n has no integer factor in the range (1, n), and thus is prime.
    return true;
}



int main()
{
    for(int i=0; i<300; ++i)
    {
        Fibonacci<unsigned long> f(i);
        if (IsPrime(f))
        {
            std::cout << f << " is a prime number\n";
        }
    }
}

Friday, November 30, 2018

Cheap Signal Analyzer



I bought this very cheap 8-input signal analyzer sometime ago on E-Bay, but since then never had time to use it, mostly due to the driver available was for Windows only.  But a few days ago, I plugged it in on my Linux Mint and googled based on VID I found, I stumbled upon a cool opensource project called "SigOk", a complete project to support various embedded instruments, including my signal analyzer.  It comes with a nice GUI front-end called "PulseView".