0

In my code, I need to build dynamic multidimensional arrays (matrices). I'm using malloc and free to do this, and yes, I know this is not C++ style. The problem is that I get error on freeing the array sometimes, randomly, not always!

Allocation code:

void allocate_memory(const int &cpiw, const int &cpih)
{
    if (_hist == nullptr)
    {
        _hist = (float ***)malloc(cpih * sizeof(float **));
        for (int i = 0; i < cpih; ++i)
        {
            _hist[i] = (float **)malloc(cpiw * sizeof(float *));
            for (int j = 0; j < cpiw; ++j)
            {
                _hist[i][j] = (float *)malloc(bins * sizeof(float));
            }
        }
    }
    _cpiw = cpiw;
    _cpih = cpih;
}

Freeing (deallocation) code:

void free_memory()
{
    if (_hist != nullptr)
    {
        for (i = 0; i < _cpih; ++i)
        {
            for (j = 0; j < _cpiw; ++j)
            {
                free(_hist[i][j]);
            }
            free(_hist[i]);
        }
        free(_hist);
        _hist = nullptr;
    }
}

My code frees and reallocates the arrays in a loop with 20 iterations. The strangest thing is that the error always occurs (if occurs) in 3rd iteration, always in 'freeing' code, and always in most inner loop (free(_hist[i][j]);). As I said, error raises randomly, and I get three different errors:

  1. Segmentation fault (core dumped)
  2. *** Error in `./hog': munmap_chunk(): invalid pointer: 0x... *** Aborted (core dumped)
  3. *** Error in `./hog': double free or corruption (out): 0x... *** Aborted (core dumped)

I get no error on allocation, mallocs never return nullptr. If I comment out the 'freeing' code, everything goes fine, no error, no overflow, no 'out of memory'. But I know this is not OK, and I must free the array.

Edit: Call stack on error:

__GI_raise(int sig) (/build/glibc-itYbWN/glibc-2.26/sysdeps/unix/sysv/linux/raise.c:51)
__GI_abort() (/build/glibc-itYbWN/glibc-2.26/stdlib/abort.c:90)
__libc_message(enum __libc_message_action action, const char * fmt) (/build/glibc-itYbWN/glibc-2.26/sysdeps/posix/libc_fatal.c:181)
malloc_printerr(mstate ar_ptr, void * ptr, const char * str, int action) (/build/glibc-itYbWN/glibc-2.26/malloc/malloc.c:5426)
munmap_chunk(mchunkptr p) (/build/glibc-itYbWN/glibc-2.26/malloc/malloc.c:2877)
__GI___libc_free(void * mem) (/build/glibc-itYbWN/glibc-2.26/malloc/malloc.c:3138)
hn::hog::free_memory() (/home/.../CProjects/HOG/hn_hog.h:320)
hn::hog::extractHOG_jpg(const JSAMPROW * image, const int & iw, const int & ih, const int & cw, const int & ch, const int & bw, const int & bh, const int & bins, const int & isunsigned) (/home/.../CProjects/HOG/hn_hog.h:458)
main(int argc, char ** argv) (/home/.../CProjects/HOG/main.cpp:168)

Edit: Problem solved. Sorry everyone and moderators. By more and more debugging, finally I found out that somewhere in my code 'out-of-bounds' writes (on negative indices) were occurring. Thanks everyone.

h.nodehi
  • 1,036
  • 1
  • 17
  • 32
  • Are you making sure that `cpih` is assigned to `_cpih` nad `cpiw` is assigned to `_cpiw`? – R Sahu May 09 '18 at 22:06
  • 5
    In cases like this, it's almost impossible to say where things could go wrong without looking at a [mcve]. – R Sahu May 09 '18 at 22:06
  • Which line in the code that you show is `hn_hog.h:320`? – hlt May 09 '18 at 22:08
  • @RSahu yes, `_cpih` and `_cpiw` always have the updated value. I edited the code. – h.nodehi May 09 '18 at 22:19
  • @hlt This: `free(_hist[i][j]);`. As I've mentioned, error always occurs at this line. – h.nodehi May 09 '18 at 22:21
  • Probably not related: [Keep an eye on the rules for using underscores in identifiers.](https://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) – user4581301 May 09 '18 at 22:59
  • What is the scope of i and j in free_memory? Could another thread be altering these values? – Kyle Huff May 09 '18 at 23:16
  • @KyleHuff they are static inside the function (free_memory). No threading at all. – h.nodehi May 09 '18 at 23:28
  • 1
    Well then I don't see anything wrong with the code. I have to guess that the heap is getting corrupted somewhere else. – Kyle Huff May 09 '18 at 23:35
  • 1
    Often mistakes like out-of-bounds memory writes won't cause errors immediately, only later when you try to allocate or deallocate memory. A tool like valgrind might help find the actual source of such a mistake. – aschepler May 09 '18 at 23:56
  • @KyleHuff and everyone, yes, my code was corrupting the heap. – h.nodehi May 09 '18 at 23:57

0 Answers0