I believe I have a declaration incorrect. I have an array that is 2D and an array that is 3D. I'm seg faulting because I'm assigning the value 0 -- or NULL to one of the arrays. I know this is trying to assign the address NULL to the pointer which is invalid.
Maybe I need to dereference the array before assigning? If so, how do I do this? If not, how do I need to declare the arrays?
double **WeightIH = calloc(51*20,sizeof(double **));
double ***Input = calloc(51*40, sizeof(double ***));
DeltaWeightIH[i][j] = 0.0 ;
the easiest way is to use for loops. just like the example below
int i, j = 0;
int rows = 5;
int cols = 2;
int rows2 = 3; // for 3d array
double **arr2d = (double **)calloc(rows, sizeof(double));
double ***arr3d = (double ***)calloc(rows, sizeof(double));
for (i = 0; i < rows; j++)
{
arr2d[i] = (double *)calloc(cols, sizeof(double));
}
arr2d[1][2] = 0.0; //Or *(*(arr2d+1)+2) = 0.0;
//the same thing for 3d it just need another for loop.
for (i = 0; i < rows; j++)
{
arr3d[i] = (double **)calloc(cols, sizeof(double));
for (j = 0; i < cols; j++)
{
arr3d[i][j] = (double *)calloc(rows2, sizeof(double));
}
}
arr3d[1][2][1] = 0.0; //Or *(*(*(arr2d+1)+2)+1) = 0.0;
A simple way to define 5x6x7 matrix hope it helps.
float ***array3D;
array3D = malloc(5 * sizeof(float**));
for ( int i = 0; i < 5; ++i) {
array3D[i] = malloc(6 * sizeof(float*));
for ( int j = 0; j < 6; ++j) {
array3D[i][j] = calloc( 7, sizeof(float));
for ( int k = 0; k < 7; ++k )
array3D[i][j][k] = 1.0;
}
}
I wouldn't use calloc when define array of pointers since you filling them immediately in the same loop.
Don't forget to free, it will eat your memory very quick.
It's not clear from your question whether a contiguous array would satisfy your requirements; but if it does then you can write more simply:
double (*a)[20] = malloc( 51 * sizeof *a );
double (*b)[20][30] = malloc( 10 * sizeof *b );
The innermost dimension goes on the right-hand-side, the other dimensions go on the left.
If you really do need a jagged array you need to write separate allocations for each row.
Related
If I allocate memory with malloc I get a contiguous chunk of memory:
typedef struct s_point
{
float x;
float y;
float z;
float w;
} t_point;
t_point *matrix = malloc(sizeof(t_point) * (i * j));
But then how can I do something like:
matrix[x][y] = data;
On it? If it it is just a pointer and not a pointer pointer?
If you allocated a one dimensional array that simulates a two-dimensional array like
t_point *matrix = malloc(sizeof(t_point) * (m * n));
where m is the number of rows and n is the number of columns.
Then for two indices i and j you can write for example
for ( size_t i = 0; i < m; i++ )
{
for ( size_t j = 0; j < n; j++ )
{
matrix[i * n + j] = data;
}
}
Actually it is the same if to write
for ( size_t i = 0; i < m * n; i++ )
{
matrix[i] = data;
}
In the both cases the variable data must have the type t_point. Otherwise you need to assign each data member of objects separately as for example
for ( size_t i = 0; i < m * n; i++ )
{
matrix[i].x = x;
matrix[i].y = y;
matrix[i].z = z;
matrix[i].w = w;
}
You can use a pointer to Variable Length Array:
t_point (*matrix)[n] = malloc(sizeof(t_point[m][n]));
It allocates a contiguous chunk of memory where individual elements are accessible via matrix[i][j]. Just remember to call free(matrix) when the memory is no longer needed.
Vlad's and tstanisl's answers are great.
Another way, that support matrix[x][y] syntax, doesn't use VLA and allocate just two continous chunks of memory:
t_point* buf = malloc(sizeof(t_point) * rows * cols);
t_point** matrix = malloc(sizeof(t_point*) * rows);
for(unsigned i = 0; i<rows; ++i) {
matrix[i] = buf + (i*cols);
}
// ...
free(buf);
free(matrix);
It also allows you to do tricks like swapping rows by just reassigning pointers (I don't know if that happens with matrices, but it is sometimes handy with something like argv). If you don't need that, I would probably go for Vlad's method
I created this function to allocate dynamically a 3D array.
int ***create_3D_Array(int nb_block, int nb_lin, int nb_col) {
int i, j;
int ***A = (int***)malloc(nb_block * sizeof(int**));
for (i = 0; i <nb_col; i++) {
A[i] = (int**)malloc(nb_col * sizeof(int*));
for (j = 0; j < nb_lin; j++) {
A[i][j] = (int*)malloc(nb_lin * sizeof(int));
}
}
return A;
}
I then used it here
int ***all_blocks = NULL;
all_blocks = create_3D_Array(54, 5, 5);
However, it is not working correctly because when I want to give a value to my 6th block all_blocks[5], the program stops working.
Is there any error in my function ?
The dimensions are incorrect in your allocation loops. The outer loop should run to nb_block, the second malloc should allocate nb_lin * sizeof(int*) and the third malloc should allocate nb_col * sizeof(int).
Here is a corrected version:
int ***create_3D_Array(int nb_block, int nb_lin, int nb_col) {
int i, j;
int ***A = (int***)malloc(nb_block * sizeof(int**));
for (i = 0; i < nb_block; i++) {
A[i] = (int**)malloc(nb_lin * sizeof(int*));
for (j = 0; j < nb_lin; j++) {
A[i][j] = (int*)malloc(nb_col * sizeof(int));
}
}
return A;
}
Note that it might be simpler to use a direct 3D array:
int (*all_blocks)[5][5] = malloc(54 * sizeof(*all_blocks));
I have this struct called Grid that holds a 2d array of strings. I'v been searching on how to free multidimensional arrays properly and can't seem to find the problem with this procedure as valgrind keeps detecting errors and leaked memory. Thanks in advance!
typedef struct Grid{
int N;
int M;
char ***adj;
}TGrid;
TGrid* emptyGrid(int N, int M){
int i,j;
TGrid *Grid = malloc(sizeof(TGrid));
Grid->N = N;
Grid->M = M;
Grid->adj = malloc(N * sizeof(char ***));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char **));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char *));
}
}
return Grid;
}
void freeGrid(TGrid *Grid){
int i, j;
for(i = 0; i < Grid->N; i++){
for(j = 0; j < Grid->M; j++){
free(Grid->adj[i][j]);
}
free(Grid->adj[i]);
}
free(Grid->adj);
free(Grid);
}
The way you malloc memory is incorrect, proper ways should be:
TGrid* emptyGrid(int N, int M){
int i,j;
TGrid *Grid = malloc(sizeof(TGrid));
Grid->N = N;
Grid->M = M;
Grid->adj = malloc(N * sizeof(char **));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char *));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char));
}
}
return Grid;
}
Note that, Grid->adj[i][j] always points to array of 10 char, you can use this:
#include <stdio.h>
#include <stdlib.h>
typedef struct Grid{
int N;
int M;
char (**adj)[10];
}TGrid;
TGrid* emptyGrid(int N, int M){
int i;
TGrid *Grid = malloc(sizeof(TGrid));
Grid->N = N;
Grid->M = M;
Grid->adj = malloc(N * sizeof(char (*)[10]));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char[10]));
}
return Grid;
}
void freeGrid(TGrid *Grid){
int i;
for(i = 0; i < Grid->N; i++){
free(Grid->adj[i]);
}
free(Grid->adj);
free(Grid);
}
int main() {
TGrid* t = emptyGrid(2,3);
freeGrid(t);
return 0;
}
However, since free receives a void* parameter, there must be something else in your code.
The general structure of your code is fine, but the types under sizeof are wrong. The general idiom for malloc-ing memory looks as follows
T *p = malloc(N * sizeof *p);
or, equivalently
T *p = malloc(N * sizeof(T));
Note that in the latter (type-based) variant there's one less asterisk under sizeof than there's is in the recipient pointer type.
That's exactly how it should be in your case as well
Grid->adj = malloc(N * sizeof(char **));
/* Since `Grid->adj` is `char ***`, you should have `char **` under `sizeof` */
...
Grid->adj[i] = malloc(M * sizeof(char *));
/* Since `Grid->adj[i]` is `char **`, you should have `char *` under `sizeof` */
...
Grid->adj[i][j] = malloc(10 * sizeof(char));
/* Since `Grid->adj[i][j]` is `char *`, you should have `char` under `sizeof` */
If that's not what you need, then there must be something wrong with your types. There's no way to say without knowing your intent.
(And I would suggest you use the first approach to specifying sizeof under malloc - use expressions, not types. That way you won't have to count asterisks.)
However, in real life this specific error would typically only result in over-allocated memory. No out-of-bound access or memory leaks should occur. If valgrind reports such errors, there must be something else at work here as well.
It's difficult to see where the problem is since you haven't posted the code that uses the functions.
I want to point out that the calls to malloc need to be changed.
You have:
Grid->adj = malloc(N * sizeof(char ***));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char **));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char *));
}
}
Those calls need to be changed to:
Grid->adj = malloc(N * sizeof(char **));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(char *));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(char));
}
}
You can avoid such errors by using a coding style as follows:
Grid->adj = malloc(N * sizeof(*(Grid->adj)));
for(i = 0; i < N; i++){
Grid->adj[i] = malloc(M * sizeof(*(Grid->adj[i])));
for(j = 0; j < M; j++){
Grid->adj[i][j] = malloc(10 * sizeof(*(Grid->adj[i][j])));
}
}
A simpler case that uses the same style:
char* cp = malloc(10*sizeof(*cp));
You are not allocating arrays, you are allocating pointer-based look-up tables. The only reason for doing so is if you wish the individual dimensions to have different lengths (such as in an array of strings). If you don't need that, you should never use pointer-to-pointer tables since they are slow, error-prone and needlessly complex.
To allocate an actual 3D array, you would do like this:
char (*array)[Y][Z] = malloc ( sizeof(char[X][Y][Z] );
...
free(array);
To allocate an array of strings, you would do like this:
char** lookup = malloc ( sizeof( char*[N] ) );
for(size_t i=0; i<N; i++)
{
lookup[i] = ...; // assign pointers to strings
}
...
free(lookup);
As a rule of thumb, whenever your program contains more than two levels of indirection, the program design is most likely bad.
If I allocate a 2D array like this int a[N][N]; it will allocate a contiguous block of memory.
But if I try to do it dynamically like this :
int **a = malloc(rows * sizeof(int*));
for(int i = 0; i < rows; i++)
a[i] = malloc(cols * sizeof(int));
This maintains a unit stride between the elements in the rows, but this may not be the case between rows.
One solution is to convert from 2D to 1D, besides that, is there another way to do it?
If your array dimensions are known at compile time:
#define ROWS ...
#define COLS ...
int (*arr)[COLS] = malloc(sizeof *arr * ROWS);
if (arr)
{
// do stuff with arr[i][j]
free(arr);
}
If your array dimensions are not known at compile time, and you are using a C99 compiler or a C2011 compiler that supports variable length arrays:
size_t rows, cols;
// assign rows and cols
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
// do stuff with arr[i][j]
free(arr);
}
If your array dimensions are not known at compile time, and you are not using a C99 compiler or a C2011 compiler that supports variable-length arrays:
size_t rows, cols;
// assign rows and cols
int *arr = malloc(sizeof *arr * rows * cols);
{
// do stuff with arr[i * rows + j]
free(arr);
}
In fact, n-dimensional arrays (allocated on the stack) are really just 1-dimension vectors. The multiple indexing is just syntactic sugar. But you can write an accessor function to emulate something like what you want:
int index_array(int *arr, size_t width, int x, int y)
{
return arr[x * width + y];
}
const size_t width = 3;
const size_t height = 2;
int *arr = malloc(width * height * sizeof(*arr));
// ... fill it with values, then access it:
int arr_1_1 = index_array(arr, width, 1, 1);
However, if you have C99 support, then declaring a pointer to an array is possible, and you can even use the syntactic sugar:
int (*arr)[width] = malloc(sizeof((*arr) * height);
arr[x][y] = 42;
Say you want to dynamically allocate a 2-dimensional integer array of ROWS rows and COLS columns. Then you can first allocate a continuous chunk of ROWS * COLS integers and then manually split it into ROWS rows. Without syntactic sugar, this reads
int *mem = malloc(ROWS * COLS * sizeof(int));
int **A = malloc(ROWS * sizeof(int*));
for(int i = 0; i < ROWS; i++)
A[i] = mem + COLS*i;
// use A[i][j]
and can be done more efficiently by avoiding the multiplication,
int *mem = malloc(ROWS * COLS * sizeof(int));
int **A = malloc(ROWS * sizeof(int*));
A[0] = mem;
for(int i = 1; i < ROWS; i++)
A[i] = A[i-1] + COLS;
// use A[i][j]
Finally, one could give up the extra pointer altogether,
int **A = malloc(ROWS * sizeof(int*));
A[0] = malloc(ROWS * COLS * sizeof(int));
for(int i = 1; i < ROWS; i++)
A[i] = A[i-1] + COLS;
// use A[i][j]
but there's an important GOTCHA! You would have to be careful to first deallocate A[0] and then A,
free(A[0]);
free(A); // if this were done first, then A[0] would be invalidated
The same idea can be extended to 3- or higher-dimensional arrays, although the code will get messy.
You can treat dynamically allocated memory as an array of a any dimension by accessing it in strides:
int * a = malloc(sizeof(int) * N1 * N2 * N3); // think "int[N1][N2][N3]"
a[i * N2 * N3 + j * N3 + k] = 10; // like "a[i, j, k]"
The best way is to allocate a pointer to an array,
int (*a)[cols] = malloc(rows * sizeof *a);
if (a == NULL) {
// alloc failure, handle or exit
}
for(int i = 0; i < rows; ++i) {
for(int j = 0; j < cols; ++j) {
a[i][j] = i+j;
}
}
If the compiler doesn't support variable length arrays, that only works if cols is a constant expression (but then you should upgrade your compiler anyway).
Excuse my lack of formatting or any mistakes, but this is from a cellphone.
I also encountered strides where I tried to use fwrite() to output using the int** variable as the src address.
One solution was to make use of two malloc() invocations:
#define HEIGHT 16
#define WIDTH 16
.
.
.
//allocate
int **data = malloc(HEIGHT * sizeof(int **));
int *realdata = malloc(HEIGHT * WIDTH * sizeof(int));
//manually index
for (int i = 0; i < HEIGHT; i++)
data[i] = &realdata[i * WIDTH];
//populate
int idx = 0;
for (int i = 0; i < HEIGHT; i++)
for (int j = 0; j < WIDTH; j++)
data[i][j] = idx++;
//select
int idx = 0;
for (int i = 0; i < HEIGHT; i++)
{
for (int j = 0; j < WIDTH; j++)
printf("%i, ", data[i][j]);
printf("/n");
}
//deallocate
.
.
.
You can typedef your array (for less headake) and then do something like that:
#include <stdlib.h>
#define N 10
typedef int A[N][N];
int main () {
A a; // on the stack
a[0][0]=1;
A *b=(A*)malloc (sizeof(A)); // on the heap
(*b)[0][0]=1;
}
I have been asked in an interview how do i allocate a 2-D array and below was my solution to it.
#include <stdlib.h>
int **array;
array = malloc(nrows * sizeof(int *));
for(i = 0; i < nrows; i++)
{
array[i] = malloc(ncolumns * sizeof(int));
if(array[i] == NULL)
{
fprintf(stderr, "out of memory\n");
exit or return
}
}
I thought I had done a good job but then he asked me to do it using one malloc() statement not two. I don't have any idea how to achieve it.
Can anyone suggest me some idea to do it in single malloc()?
Just compute the total amount of memory needed for both nrows row-pointers, and the actual data, add it all up, and do a single call:
int **array = malloc(nrows * sizeof *array + (nrows * (ncolumns * sizeof **array));
If you think this looks too complex, you can split it up and make it a bit self-documenting by naming the different terms of the size expression:
int **array; /* Declare this first so we can use it with sizeof. */
const size_t row_pointers_bytes = nrows * sizeof *array;
const size_t row_elements_bytes = ncolumns * sizeof **array;
array = malloc(row_pointers_bytes + nrows * row_elements_bytes);
You then need to go through and initialize the row pointers so that each row's pointer points at the first element for that particular row:
size_t i;
int * const data = array + nrows;
for(i = 0; i < nrows; i++)
array[i] = data + i * ncolumns;
Note that the resulting structure is subtly different from what you get if you do e.g. int array[nrows][ncolumns], because we have explicit row pointers, meaning that for an array allocated like this, there's no real requirement that all rows have the same number of columns.
It also means that an access like array[2][3] does something distinct from a similar-looking access into an actual 2d array. In this case, the innermost access happens first, and array[2] reads out a pointer from the 3rd element in array. That pointer is then treatet as the base of a (column) array, into which we index to get the fourth element.
In contrast, for something like
int array2[4][3];
which is a "packed" proper 2d array taking up just 12 integers' worth of space, an access like array[3][2] simply breaks down to adding an offset to the base address to get at the element.
int **array = malloc (nrows * sizeof(int *) + (nrows * (ncolumns * sizeof(int)));
This works because in C, arrays are just all the elements one after another as a bunch of bytes. There is no metadata or anything. malloc() does not know whether it is allocating for use as chars, ints or lines in an array.
Then, you have to initialize:
int *offs = &array[nrows]; /* same as int *offs = array + nrows; */
for (i = 0; i < nrows; i++, offs += ncolumns) {
array[i] = offs;
}
Here's another approach.
If you know the number of columns at compile time, you can do something like this:
#define COLS ... // integer value > 0
...
size_t rows;
int (*arr)[COLS];
... // get number of rows
arr = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < COLS; j++)
arr[i][j] = ...;
}
If you're working in C99, you can use a pointer to a VLA:
size_t rows, cols;
... // get rows and cols
int (*arr)[cols] = malloc(sizeof *arr * rows);
if (arr)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
arr[i][j] = ...;
}
How do we allocate a 2-D array using One malloc statement (?)
No answers, so far, allocate memory for a true 2D array.
int **array is a pointer to pointer to int. array is not a pointer to a 2D array.
int a[2][3] is an example of a true 2D array or array 2 of array 3 of int
To allocate memory for a true 2D array, with C99, use malloc() and save to a pointer to a variable-length array (VLA)
// Simply allocate and initialize in one line of code
int (*c)[nrows][ncolumns] = malloc(sizeof *c);
if (c == NULL) {
fprintf(stderr, "out of memory\n");
return;
}
// Use c
(*c)[1][2] = rand();
...
free(c);
Without VLA support, if the dimensions are constants, code can use
#define NROW 4
#define NCOL 5
int (*d)[NROW][NCOL] = malloc(sizeof *d);
You should be able to do this with (bit ugly with all the casting though):
int** array;
size_t pitch, ptrs, i;
char* base;
pitch = rows * sizeof(int);
ptrs = sizeof(int*) * rows;
array = (int**)malloc((columns * pitch) + ptrs);
base = (char*)array + ptrs;
for(i = 0; i < rows; i++)
{
array[i] = (int*)(base + (pitch * i));
}
I'm not a fan of this "array of pointers to array" to solve the multi dimension array paradigm. Always favored a single dimension array, at access the element with array[ row * cols + col]? No problems encapsulating everything in a class, and implementing a 'at' method.
If you insist on accessing the members of the array with this notation: Matrix[i][j], you can do a little C++ magic. #John solution tries to do it this way, but he requires the number of column to be known at compile time. With some C++ and overriding the operator[], you can get this completely:
class Row
{
private:
int* _p;
public:
Row( int* p ) { _p = p; }
int& operator[](int col) { return _p[col]; }
};
class Matrix
{
private:
int* _p;
int _cols;
public:
Matrix( int rows, int cols ) { _cols=cols; _p = (int*)malloc(rows*cols ); }
Row operator[](int row) { return _p + row*_cols; }
};
So now, you can use the Matrix object, for example to create a multiplication table:
Matrix mtrx(rows, cols);
for( i=0; i<rows; ++i ) {
for( j=0; j<rows; ++j ) {
mtrx[i][j] = i*j;
}
}
You should now that the optimizer is doing the right thing and there is no call function or any other kind of overhead. No constructor is called. As long as you don't move the Matrix between function, even the _cols variable isn't created. The statement mtrx[i][j] basically does mtrx[i*cols+j].
It can be done as follows:
#define NUM_ROWS 10
#define NUM_COLS 10
int main(int argc, char **argv)
{
char (*p)[NUM_COLS] = NULL;
p = malloc(NUM_ROWS * NUM_COLS);
memset(p, 81, NUM_ROWS * NUM_COLS);
p[2][3] = 'a';
for (int i = 0; i < NUM_ROWS; i++) {
for (int j = 0; j < NUM_COLS; j++) {
printf("%c\t", p[i][j]);
}
printf("\n");
}
} // end of main
You can allocate (row*column) * sizeof(int) bytes of memory using malloc.
Here is a code snippet to demonstrate.
int row = 3, col = 4;
int *arr = (int *)malloc(row * col * sizeof(int));
int i, j, count = 0;
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*col + j) = ++count; //row major memory layout
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
printf("%d ", *(arr + i*col + j));