0

I have 2 arrays as follows -

int **data; 
int ***count; 

After running some analysis, I want make the following assignment-

count[i][j][k] = data[i][j];

However, I keep getting Segmentation fault which I think is related to some pointer assignment issues - Can anyone suggest how I can make this assignment?

Typical values of - data[i][j] = 0/1/2.

Definition of ZALLOC:

#define ZALLOC(item,n,type)      if ((item = (type *)calloc((n),sizeof(type))) == NULL)    fatalx("Unable to allocate %d unit(s) for item\n",n)

// memory assignment
int **data; 
int nrow, ncol; 

ZALLOC(data, ncol, int *);

for (index = 0; index < ncol; index++)
{
    ZALLOC(data[index], nrow, int);
}

int g=0, index1=0, index2=2;
data[index1][index2] = g;


int ***count;
int dim1 = 100, dim2 = 1, dim3=2;
ZALLOC(count, dim1, int **);

for (i = 0; i < dim1; i++)
{
ZALLOC(count[i], dim2, int *);
for (j = 0; j < dim2; j++)
{
ZALLOC(count[i][j], dim3, int);
}
}

// Initialize
for (i = 0; i < dim1; i++)
{
    for (j = 0; j < dim2; j++)
{
    for (k = 0; k < dim3; k++)
    {
        count[i][j][k] = 0;
    }
}
}
// Assignment
count[0][1][2] = data[1][2];
user19758
  • 131
  • 1
  • 5
  • You should also attach your code. Is it a homework problem? – Dilawar Feb 25 '13 at 03:51
  • 3
    Those aren't arrays; they're pointers. How are you initializing them? – melpomene Feb 25 '13 at 03:52
  • The problem lies in either your initializations or in the indices. – asheeshr Feb 25 '13 at 03:57
  • No this is not homework.The way I am initializing it as follows -for(i = 0; i < 10; i++) – user19758 Feb 25 '13 at 03:57
  • @user19758 That only sets `i` to 10. It doesn't initialize `data` or `count`. – melpomene Feb 25 '13 at 04:02
  • Please see the updated code above. – user19758 Feb 25 '13 at 04:25
  • Can you make 2D arrays work reliably? If not, practice on 2D arrays before moving to 3D arrays. If you can manage 2D arrays, the extension to 3D is systematic (and tedious) rather than difficult. You should be creating an SSCCE ([Short, Self-Contained, Complete Example](http://sscce.org/)). The code above is not. For example, `ZALLOC()` is a non-standard macro; it presumably is an error checked typed memory allocation, but without its definition, we can't tell for sure. – Jonathan Leffler Feb 25 '13 at 04:40
  • Please see definition of ZALLOC above. I think the error is in assigning pointers incorrectly. Since I dont have too much experience with pointers, I am a little confused – user19758 Feb 25 '13 at 04:51
  • Hello all, Thank you very much for your comments - I actually figured out that the error was in assigning the 3D array (the sizes were incorrect), I have fixed the issue and the code works. – user19758 Feb 25 '13 at 05:30

1 Answers1

3

Your organization of the allocations is a bit odd. If you have 3 dimensions (lets call them levels, rows, and columns), you would normally allocate space to hold the levels, and then for each level you would allocate the space for the rows within the level, and then finally you would allocate the space for the columns within the row.

Your code seems to start in the middle (rows); then does some work at levels; and finally at the columns.

This code is a complete rewrite of yours, but it works without crashing. I've not yet validated it with valgrind; I need to upgrade the version on this machine.

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

#define ZALLOC(item, n, type) if ((item = (type *)calloc((n), sizeof(type))) == NULL) \
                                  fatalx("Unable to allocate %d unit(s) for item\n", n)

static void fatalx(const char *str, size_t n)
{
    fprintf(stderr, "%s: %zu\n", str, n);
    exit(1);
}

static int ***alloc_3d(int levels, int rows, int cols)
{
    int count = 0;
    int ***array_3d;
    ZALLOC(array_3d, levels, int **);
    for (int i = 0; i < levels; i++)
    {
        int **data;
        ZALLOC(data, rows, int *);
        array_3d[i] = data;
        for (int j = 0; j < rows; j++)
        {
            int *entries;
            ZALLOC(entries, cols, int);
            array_3d[i][j] = entries;
            for (int k = 0; k < cols; k++)
            {
                array_3d[i][j][k] = count++;
            }
        }
    }
    return array_3d;
}

static void print_3d(int ***a3d, int levels, int rows, int cols)
{
    for (int i = 0; i < levels; i++)
    {
        printf("%d:\n", i);
        for (int j = 0; j < rows; j++)
        {
            printf("   %d:  ", j);
            for (int k = 0; k < cols; k++)
                printf(" %3d", a3d[i][j][k]);
            putchar('\n');
        }
    }
}

static void free_3d(int ***a3d, int levels, int rows)
{
    for (int i = 0; i < levels; i++)
    {
        for (int j = 0; j < rows; j++)
            free(a3d[i][j]);
        free(a3d[i]);
    }
    free(a3d);
}

int main(void)
{
    int d1 = 3;
    int d2 = 5;
    int d3 = 7;
    int ***a3d = alloc_3d(d1, d2, d3);

    print_3d(a3d, d1, d2, d3);
    free_3d(a3d, d1, d2);

    return(0);
}

Output:

0:
   0:     0   1   2   3   4   5   6
   1:     7   8   9  10  11  12  13
   2:    14  15  16  17  18  19  20
   3:    21  22  23  24  25  26  27
   4:    28  29  30  31  32  33  34
1:
   0:    35  36  37  38  39  40  41
   1:    42  43  44  45  46  47  48
   2:    49  50  51  52  53  54  55
   3:    56  57  58  59  60  61  62
   4:    63  64  65  66  67  68  69
2:
   0:    70  71  72  73  74  75  76
   1:    77  78  79  80  81  82  83
   2:    84  85  86  87  88  89  90
   3:    91  92  93  94  95  96  97
   4:    98  99 100 101 102 103 104
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Dear Jonathan, Thank you very much for your response. This was exactly the problem - after correcting the assignment, I found that the code works properly. Thanks again!! – user19758 Feb 25 '13 at 05:40
  • Now checked over with `valgrind`; no problems (memory accesses or leaks) visible. – Jonathan Leffler Feb 25 '13 at 07:07