Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Allocation of a simple matrix

Name: Anonymous 2011-07-02 8:03


#ifndef __ESTDLIB_H__
#define __ESTDLIB_H__
#include <stdlib.h>

void **mcalloc(size_t nmemb, size_t mmemb, size_t size);
void mmalloc(void ***matrix,size_t n, size_t m);
void mfree(void **matrix, size_t n);
void **mrealloc(void **matrix, size_t n, size_t m, size_t nsize, size_t msize);

void **mcalloc(size_t nmemb, size_t mmemb, size_t size)
{
    return NULL;
}

void mmalloc(void ***matrix, size_t n, size_t m)
{
    register unsigned long int i, j;
    if (matrix == NULL)
        return;
    *matrix = malloc(n);
    if (*matrix == NULL)
        return;
    for (i = 0; i < n; ++i) {
        *((*matrix)+i) = malloc(m);
        if (*((*matrix)+i) == NULL)
            break;
    }
   
    if (i < n+1) {
        for (j = 0; j <= i; ++j) {
            if (*((*matrix)+j) != NULL)
                free(*((*matrix)+j));
        }
        free(*matrix);
    }

    return;
}

void mfree(void **matrix, size_t n)
{
    register size_t i;
    for (i = 0; i < n; ++i)
        free(*(matrix+i));
    free(matrix);
}

void **mrealloc(void **matrix, size_t n, size_t m, size_t nsize, size_t msize)
{
    return NULL;
}

#endif


When I'm back from 2 weeks vacation, I'll bet that /prog/ (even the wizards) haven't solved this mystery. The amount segfault and other corruptions I got from my own code was amazing. Enjoy.

Name: Anonymous 2011-07-02 8:05

if (i < n+1) should be if (i < n)

Name: Anonymous 2011-07-02 8:06

Multidimensional arrays are stupid. Just malloc(n * m * sizeof(element)).

Name: Anonymous 2011-07-02 9:21

dalloc.h
#ifndef __DALLOC_H
#define __DALLOC_H

/*
 * Allocates 2D memory of m_memb x n_memb elements
 * size bytes large.
 */
extern void **dalloc(size_t m_memb, size_t n_memb, size_t size);

/*
 * Frees the memory previously allocated by dalloc.
 */
extern void dalloc_free(void **ptr);

#endif


dalloc.c
#include <stdlib.h>
#include "dalloc.h"

void **
dalloc(size_t m_memb, size_t n_memb, size_t size)
{
  size_t i;
  void **ptr;

  ptr = (void **) malloc(m_memb * sizeof(void *));

  if (ptr == NULL)
    return NULL;

  *ptr = malloc(m_memb * n_memb * size);

  if (*ptr == NULL) {
    free(ptr);
    return NULL;
  }

  for (i = 0; i < m_memb; i++)
    ptr[i] = *ptr + i * n_memb * size;

  return ptr;
}

void
dalloc_free(void **ptr)
{
  free(*ptr);
  free( ptr);
}


Reallocation is probably marginally more difficult, but at least this ensures contiguous memory.

Name: Anonymous 2011-08-03 18:21

>>4
Outstanding sir. I must say, I feel pretty stupid of not realising such a simple solution. Still, I'm bothered by my own solution. I can allocate a matrix, but the mfree'ing makes the program abort and I know that there is a grave design error somewhere, but I can't figure it out. Could somebody give me a hint?

I rewrote the code again today (with the flaw still being there):

estdlib.h

#ifndef __ESTDLIB_H__
#define __ESTDLIB_H__
#include <stdlib.h>

void *mcalloc(size_t nmemb, size_t mmemb, size_t size);
void *mmalloc(size_t nsize, size_t msize);
void mfree(void *matrix_ptr);
void *mrealloc(void *matrix_ptr, size_t nmemb, size_t mmemb, size_t nsize, size_t msize);

void *mcalloc(size_t nmemb, size_t mmemb, size_t size)
{
    return NULL;
}

void *mmalloc(size_t n, size_t m)
{
    auto void **matrix;
    register size_t i = 0, j;   
    matrix = malloc(n+1);
    if (matrix == NULL)
        return (void *) matrix;
   
    do
        *(matrix+i) = malloc(m);
    while (i < n && matrix[i++] != NULL);
   
    if (i < n) {
        for (j = 0; j <= i; ++j) {
            if (matrix[j] != NULL)
                free(matrix[j]);
        }
        free(matrix);
        matrix = NULL;
        return (void *) matrix;
    }
    *(matrix+n) = NULL;

    return *matrix;
}

void mfree(void *matrix_ptr)
{
    auto void **matrix = (void **) matrix_ptr;
    register size_t i = 0;
    if (matrix == NULL)
        return;
   
    do
        free(&matrix[i++]);
    while (matrix[i] != NULL);
    free(matrix);

    return;
}

void *mrealloc(void *matrix_ptr, size_t nmemb, size_t mmemb, size_t nsize, size_t msize)
{
    return NULL;
}

#endif


estdlib.c

#include <stdio.h>
#include "estdlib.h"

int main(int argc, char *argv[])
{
   
    auto unsigned int i, j, n = 5, m = 5;
    auto unsigned int **matrix = (unsigned int **) mmalloc(sizeof(*matrix)*n,sizeof(**matrix)*m);
    for (i = 0; i < n; ++i) {
        for (j = 0; j < m; ++j)
            matrix[i][j] = i+j;
    }
   
    for (i = 0; i < n; ++i) {
        for (j = 0; j < m; ++j)
            printf("%4u%c",matrix[i][j],j+1<m?' ':'\n');
    }
    mfree((void *) matrix);
    matrix = NULL;
    return 0;
}


Compile with:
gcc -ansi -pedantic -Wall -O0 -o estdlib estdlib.c

When executed, prints the following message:

*@star:~/devel/c$ ./estdlib
   0    1    2    3    4
   1    2    3    4    5
   2    3    4    5    6
   3    4    5    6    7
   4    5    6    7    8
*** glibc detected *** ./estdlib: double free or corruption (out): 0x0000000001758050 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x78a8f)[0x7f3822ab3a8f]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x73)[0x7f3822ab78e3]
./lstdlib[0x4006d1]
./lstdlib[0x400821]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xff)[0x7f3822a59eff]
./lstdlib[0x4004c9]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:03 665109                             /home/*/devel/c/estdlib
00600000-00601000 r--p 00000000 08:03 665109                             /home/*/devel/c/estdlib
00601000-00602000 rw-p 00001000 08:03 665109                             /home/*/devel/c/estdlib
01758000-01779000 rw-p 00000000 00:00 0                                  [heap]
7f381c000000-7f381c021000 rw-p 00000000 00:00 0
7f381c021000-7f3820000000 ---p 00000000 00:00 0
7f3822825000-7f382283a000 r-xp 00000000 08:03 623067                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f382283a000-7f3822a39000 ---p 00015000 08:03 623067                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3822a39000-7f3822a3a000 r--p 00014000 08:03 623067                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3822a3a000-7f3822a3b000 rw-p 00015000 08:03 623067                     /lib/x86_64-linux-gnu/libgcc_s.so.1
7f3822a3b000-7f3822bc5000 r-xp 00000000 08:03 622980                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3822bc5000-7f3822dc4000 ---p 0018a000 08:03 622980                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3822dc4000-7f3822dc8000 r--p 00189000 08:03 622980                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3822dc8000-7f3822dc9000 rw-p 0018d000 08:03 622980                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3822dc9000-7f3822dcf000 rw-p 00000000 00:00 0
7f3822dcf000-7f3822df0000 r-xp 00000000 08:03 622977                     /lib/x86_64-linux-gnu/ld-2.13.so
7f3822fc9000-7f3822fcc000 rw-p 00000000 00:00 0
7f3822fec000-7f3822fef000 rw-p 00000000 00:00 0
7f3822fef000-7f3822ff0000 r--p 00020000 08:03 622977                     /lib/x86_64-linux-gnu/ld-2.13.so
7f3822ff0000-7f3822ff2000 rw-p 00021000 08:03 622977                     /lib/x86_64-linux-gnu/ld-2.13.so
7fffa7f75000-7fffa7f96000 rw-p 00000000 00:00 0                          [stack]
7fffa7fff000-7fffa8000000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted

Name: 3 2011-08-03 18:25

I didn't look at your code, but as I said before, allocating matrix rows is completely retarded. Just malloc(n * m * sizeof(element)).

Name: Anonymous 2011-08-03 18:43

>>6
True and I know that I can use pointer arithmetic and % to do the memory address calculations. Sorry but I have a habit of first implementing a working naive solution and then think about how one could improve it; not some constant reduction but asymptotically.

Name: Anonymous 2011-08-03 22:05


#include <stdio.h>
#include <stdlib.h>

void *mmalloc(size_t ymemb, size_t xmemb, size_t size) {
        void **m;
        size_t y;

        if (!(m = malloc(ymemb * sizeof *m)))
                goto error_1;

        for (y = 0; y < ymemb; y++)
                if (!(m[y] = malloc(xmemb * size)))
                        goto error_2;

        return m;

error_2:
        for (; y > 0; y--)
                free(m[y]);
error_1:
        return NULL;
}

void mfree(void *m, size_t xmemb) {
        for (; xmemb > 0; xmemb--)
                free(((void **)m)[xmemb]);
        free(m);
}

#define Y 4
#define X 3
int main(void) {
        int **m, x, y;

        if (!(m = mmalloc(Y, X, sizeof **m)))
                return 1;

        for (y = 0; y < Y; y++)
                for (x = 0; x < X; x++)
                        m[y][x] = y * x + x + 1;

        for (y = 0; y < Y; y++) {
                for (x = 0; x < X; x++)
                        printf("%2d\t", m[y][x]);
                putchar('\n');
        }

        mfree(m, Y);

        return 0;
}

Name: Anonymous 2011-08-03 22:54

This thread is crap and the code is terrible.

Name: Anonymous 2011-08-04 0:46

>>3
It's way too much of a pain to have to calculate index location by yourself. ...It could be slightly better if I use macros though. Anyway my 2D array allocation and free as macros.

/* 2D array alloc */
#define MALLOC2(TYPE,I,m,n) \
     ({ \
          int i; \
          I = (TYPE**) malloc((m)*sizeof(TYPE*));                   \
          for(i=0; i<(m); i++) I[i] = (TYPE*) malloc((n)*sizeof(TYPE)); \
     })

#define FREE2(I,m) \
     ({            \
     int i;        \
     for(i=0; i<m; i++) free(I[i]); \
     free(I); \
     })

Name: Anonymous 2011-08-04 0:55

>>7
NO you retard. Do what >>6 says!

Name: Anonymous 2011-08-04 1:09

And maintain the length of rows as state?

Name: Anonymous 2011-08-04 4:19

>>12
yes

Name: Anonymous 2011-08-04 5:31


                __ __
      /    /   /  /_/
     /__  / __/  /

        /  .  \
       /   '   \
      /    |    \
     /           \
    /      |      \

Name: Anonymous 2011-08-04 6:19

If C is simpler and more elegant than C++, why does all the code in this thread suck balls?


template<int M, int N>
class matrix
{
public:
   int rows() const
   {
      return M;
   }
  
   int columns() const
   {
      return N;
   }

   float operator [](int M_, int N_)
   {
      return members[(M_ * N) + N_];
   }

   // the rest is left as an exercise for the reader
private:
   float members[M * N * sizeof(float)];
};

Name: Anonymous 2011-08-04 6:50

>>15
B-b-but C++ templates have too much overhead. I know this b-b-because my ANSI C professor told me so.

Name: Anonymous 2011-08-04 6:57

>>15
#include <stdio.h>
#include <math.h>

#define DECL_MATRIX(name, m, n) float name[(m)][(n)]
#define MATRIX_ROWS(x) (sizeof(x) / sizeof(x[0]))
#define MATRIX_COLUMNS(x) (sizeof(x[0]) / sizeof(x[0][0]))

int main()
{
    DECL_MATRIX(anus, 3, 4);
    size_t i, j;
    for (i = 0; i < MATRIX_ROWS(anus); i++)
    {
      for (j = 0; j < MATRIX_COLUMNS(anus); j++)
      {
        anus[i][j] = sqrt(i * j);
      }
    }

    printf("Anus dimensions: %u x %u\n", MATRIX_ROWS(anus), MATRIX_COLUMNS(anus));
    for (i = 0; i < MATRIX_ROWS(anus); i++)
    {
      for (j = 0; j < MATRIX_COLUMNS(anus); j++)
      {
        printf("%f ", anus[i][j]);
      }
      putchar('\n');
    }
    return 0;
}

Name: Anonymous 2011-08-04 8:36

>>15
See >>4.

Name: Anonymous 2011-08-04 8:41

>>18
That code is hideous and unnecessarily obscure.

Name: Anonymous 2011-08-04 8:43

>>15
- float members[M * N * sizeof(float)];
+ float members[M * N];

Name: Anonymous 2011-08-04 9:09

>>19
You really think that is obscure?

Name: Anonymous 2011-08-04 9:25

>>21
Yes it uses pointer arithmetic.

Name: >>19 2011-08-04 9:58

Though I don't necessarily disagree with what >>22 said, I thought it necessary to point out that I am not him.

Name: Anonymous 2011-08-04 11:31

>>5
auto is implicit wherever valid, you need not specify it.

Name: Anonymous 2011-08-04 14:11

I'M PROGRAMMER
SON OF A BITCH C
C IS PIG
DO YOU WANT A COMPLETELY ILLEGIBLE CODE?
DO YOU WANT A BUFFER OVERFLOW?
C IS PIG DISGUSTING
DENNIS RITCHIE IS A MURDERER
FUCKING COMPUTER

Name: Anonymous 2011-08-04 14:24

If you sincerely believe that >>4 is hard to read you need to re-evaluate your decision to visit a programming textboard, there are two things happening and rest is error checking.

Name: Anonymous 2011-08-04 14:49

Contiguous memory is important, stop mallocing inside of loops.

Name: 5 2011-08-04 15:16

>>27
Is it to avoid memory fragmentation?
If yes, doesn't it become problematic when the memory is very fragmented and you want to allocate a very large block?

Name: Anonymous 2011-08-04 15:21

>>28
It's also very bad for memory caching, which is basically the thing that matter the most for performance nowadays.

Name: Anonymous 2011-08-04 17:39

>>28
Once you have virtual memory (which every OS now has), you don't have to worry about allocating large blocks. They would be spread out in physical memory if there is no contiguous space. And yeah, contiguous memory is important b/c of caching.

Name: Anonymous 2011-08-04 18:18

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Name: Anonymous 2011-08-04 18:48

Some reasons as to why contiguous memory is good http://en.wikipedia.org/wiki/Locality_of_reference

Name: Anonymous 2011-08-04 19:33

>>26
If you believe >>4 is a good way of allocating a matrix, then you need to stop programming.

Name: Anonymous 2011-08-04 19:50

>>33

Suck my cock, faggot.

Don't change these.
Name: Email:
Entire Thread Thread List