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.

Answer from unwind on Stack Overflow
Top answer
1 of 9
47

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.

2 of 9
15
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;
}
🌐
Eskimo
eskimo.com › ~scs › cclass › int › sx9b.html
23.2: Dynamically Allocating Multidimensional Arrays
#include <stdlib.h> int **array; ... NULL) { fprintf(stderr, "out of memory\n"); exit or return } } array is a pointer-to-pointer-to-int: at the first level, it points to a block of pointers, one for each row....
Discussions

im having malloc problems with a double 2d array
Why don’t you just allocate a single array?: static double *allocArray2D(size_t rows, size_t cols, size_t esz) { void *ret; int e; if(rows > SIZE_MAX / cols || (rows*=cols) > SIZE_MAX / esz) {errno = EDOM; return 0;} e = errno; errno = 0; ret = malloc(rows * esz); if(!ret) {if(!errno) errno = ENOMEM; return 0;} errno = e; return ret; } … size_t size = …, workload = …; double *arr; // And `workload+2` can overflow. if(workload > SIZE_MAX - 2) {errno = EDOM; return 0;} arr = allocArray2D(workload+2, size, sizeof *arr); That’ll do it safely and without accidentally overflowing int, which is UB. (int is an exceptionally bad size type, of course. size_t must cover at least the positive int range, it must be unsigned so no overflow UB—wraparound instead—and it’s the size type used by the C implementation for sizeof, offsetof, alignof, alignas, array dimensions, string/buffer lengths, and allocation functions’ size/align args.) Yours isn’t a 2D array, it’s a 1D array of pointers to 1D arrays (or null. maybe); there’s no reason for the indirect layer, though, it’s only going to irritate your CPU a tad. You’d use one for a row-sparse, column-dense structure, or one where each row can have a different length. Of course, per VLAless C, indexing a 2D array of arbitrary dimension requires a bit of arithmetic: #define a2drow(ARR, NCOLS, ROW)((ARR)+(ROW)*(size_t)(NCOLS)) a2drow(arr, size, i)[j] = 1; But with VLA types (C99 && !defined __STDC_NO_VLA__ but IIRC C23 makes VLA type usage legal regardless as long as you aren’t creating a local VLA), you can do it more cleanly: double (*arr)[][size]; arr = allocArray(…); (*arr)[i][j] = 0; More on reddit.com
🌐 r/cprogramming
7
2
January 4, 2024
Malloc a 2D array in C - Stack Overflow
Every time I allocate the memory for a 2D array first I create an array of int** and then with a for I allocate the memory for each element. For example: int ** arr = malloc(N*sizeof(int *)); for... More on stackoverflow.com
🌐 stackoverflow.com
How to cudaMalloc two-dimensional array ?
May be a dumb question … however, I still can’t make it work :-) When allocationg something like this: int* pArray; cudaMalloc((void**)&pArray, 10 * sizeof(int)); everything works as expected. However, what should be done to allocate and array of 10x10 ints ? More on forums.developer.nvidia.com
🌐 forums.developer.nvidia.com
0
0
June 10, 2008
c - How to malloc 2D arrays? - Stack Overflow
I need to create a two dimensional array. Presently I created it as int a[100][100] but I need to allocate the memory dynamically using malloc in C language. I used the code #include More on stackoverflow.com
🌐 stackoverflow.com
🌐
Diveintosystems
diveintosystems.org › book › C2-C_depth › arrays.html
2.5.1. Single-Dimensional Arrays
Make multiple calls to malloc, allocating an array of arrays. First, allocate a 1D array of N pointers to the element type, with a 1D array of pointers for each row in the 2D array. Then, allocate N 1D arrays of size M to store the set of column values for each row in the 2D array.
🌐
Reddit
reddit.com › r/cprogramming › im having malloc problems with a double 2d array
r/cprogramming on Reddit: im having malloc problems with a double 2d array
January 4, 2024 -

the task is to use MPI in distributed memory to take average of 4 adjacent values in a (size x size) matrix, and the start/end/workload are areas worked out for each process to do the maths, then the edges of those areas are exchanged (note that top and bottom row are untouched calculation wise, but necessary to do other rows) this is repeated until a certain precision is met in the overall calculation I cant seem to figure out what to do with my array creation as it keeps giving me segmentation fault error (11), signal code (128) any help is appreciated, thank u in advance

this function takes

  • size (size of matrix, column in my case)

  • workload (the amount of lines each process will do maths)

  • start (starting position in the array)

  • end (end position in the array

the current inputs are:

  • size = 30

processes = 6 so the split work for a 30x30 array would be:

  • proc rank0 = workload = 5 (start = 1, end = 6)

  • proc rank1 = workload = 5 (start = 6, end = 11)

  • proc rank2 = workload = 5 (start = 11, end = 16)

  • proc rank3 = workload = 5 (start = 16, end = 21)

  • proc rank4 = workload = 4 (start = 21, end = 25)

  • proc rank5 = workload = 4 (start = 25, end = 29)

double** createArray(int size, int workload, int start, int end, int rank){
printf("\t rank:%d\n", rank);
printf("\t workload:%d", workload);
printf("\t start:%d", start);
printf("\t end:%d", end);
//declare array
//double **arr;
//memory is allocated for the matrix

double** arr = (double**) malloc(sizeof(double*)*(workload+2));
for (int i=0; i<size; i++){
    arr[i] = malloc(sizeof(double)*size);
}

//writes the start vlaues into the matrix
//we need workload and extra edges each
for (int i=start-1; i<end+1; i++){
    for (int j=0; j<size; j++){
        //the upper and left rows are set to 1
        if (i==0){
            arr[i][j] = 1;
        }
        else if (j==0){
            arr[i][j] = 1;
        }
        //other elements are set to 0 
        else{
            arr[i][j] = 0;
        }
    }
    printf("\n");
}

if(rank == 0){
    for (int i=start-1; i<end+1; i++){
        for (int j=0; j<end; j++){
            printf("%lf", arr[i][j]);
        }
        printf("\n");
    }
}
*/
//returns the array 
return arr;

}

Top answer
1 of 2
2
Why don’t you just allocate a single array?: static double *allocArray2D(size_t rows, size_t cols, size_t esz) { void *ret; int e; if(rows > SIZE_MAX / cols || (rows*=cols) > SIZE_MAX / esz) {errno = EDOM; return 0;} e = errno; errno = 0; ret = malloc(rows * esz); if(!ret) {if(!errno) errno = ENOMEM; return 0;} errno = e; return ret; } … size_t size = …, workload = …; double *arr; // And `workload+2` can overflow. if(workload > SIZE_MAX - 2) {errno = EDOM; return 0;} arr = allocArray2D(workload+2, size, sizeof *arr); That’ll do it safely and without accidentally overflowing int, which is UB. (int is an exceptionally bad size type, of course. size_t must cover at least the positive int range, it must be unsigned so no overflow UB—wraparound instead—and it’s the size type used by the C implementation for sizeof, offsetof, alignof, alignas, array dimensions, string/buffer lengths, and allocation functions’ size/align args.) Yours isn’t a 2D array, it’s a 1D array of pointers to 1D arrays (or null. maybe); there’s no reason for the indirect layer, though, it’s only going to irritate your CPU a tad. You’d use one for a row-sparse, column-dense structure, or one where each row can have a different length. Of course, per VLAless C, indexing a 2D array of arbitrary dimension requires a bit of arithmetic: #define a2drow(ARR, NCOLS, ROW)((ARR)+(ROW)*(size_t)(NCOLS)) a2drow(arr, size, i)[j] = 1; But with VLA types (C99 && !defined __STDC_NO_VLA__ but IIRC C23 makes VLA type usage legal regardless as long as you aren’t creating a local VLA), you can do it more cleanly: double (*arr)[][size]; arr = allocArray(…); (*arr)[i][j] = 0;
2 of 2
1
Your alloc loop termination condition looks wrong.
🌐
Cython
cython.readthedocs.io › en › latest › src › tutorial › memory_allocation.html
Memory Allocation — Cython 3.3.0a0 documentation
import random from cython.cimports.libc.stdlib import malloc, free def random_noise(number: cython.int = 1): i: cython.int # allocate number * sizeof(double) bytes of memory my_array: cython.p_double = cython.cast(cython.p_double, malloc( number * cython.sizeof(cython.double))) if not my_array: raise MemoryError() try: ran = random.normalvariate for i in range(number): my_array[i] = ran(0, 1) # ... let's just assume we do some more heavy C calculations here to make up # for the work that it takes to pack the C double values into Python float # objects below, right after throwing away the existing objects above.
🌐
GitHub
gist.github.com › 1249305 › ac4f4190c26110fe2791a1e7a6bed9c733b3413f
Copy-less bindings of C-generated arrays with Cython · GitHub
Parameters: ----------- nx: int Number of image rows data_ptr: void* Pointer to the data """ self.data_ptr = data_ptr self.nx = nx self.ny = ny cdef as_ndarray(self, int nx, int ny, void* data_ptr): """Create an `ndarray` that doesn't own the memory, we do.""" cdef np.npy_intp shape[2] cdef np.ndarray ndarray self.set_data(nx, ny, data_ptr) shape[:] = (self.nx, int(self.ny/2)+1) # Create a 2D array, of length `nx*ny/2+1` ndarray = np.PyArray_SimpleNewFromData(2, shape, complex_typenum, self.data_ptr) ndarray.base = <PyObject*> self # without this, data would be cleaned up right away Py_INCREF(self) return ndarray def __dealloc__(self): """ Frees the array. This is called by Python when all the references to the object are gone.
Find elsewhere
🌐
Nerd Paradise
nerdparadise.com › programming › create2darray
Creating a 2D Array in Java, C#, Python, JavaScript, and C : Nerd Paradise
Once this function is over, these values will be reclaimed. If you want to allocate to the heap, then you have to use malloc and have to work with pointers. Since an array is really just a pointer to the first item in the array and a grid is an array of arrays, the type for a 2D grid of integers ...
🌐
Sololearn
sololearn.com › en › Discuss › 116505 › how-can-i-create-a-2d-dynamic-array-using-malloc-in-c
How can I create a 2D dynamic array using malloc() in C? | Sololearn: Learn to code for FREE!
int **arr = (int **)malloc(row * sizeof(int *)); for (i=0; i<row; i++) arr[i] = (int *)malloc(column * sizeof(int)); for more details check out: http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/ 4th Dec 2016, 3:20 AM · Nikunj Arora ...
🌐
University of Oslo
uio.no › studier › emner › matnat › ifi › IN3200 › v19 › teaching-material › multidimarrays.pdf pdf
Multidimensional arrays in C malloc
And after you are done with an array remember to free the memory. ... For each call to malloc you should have a corresponding free . ... In the memory of a computer there is no such thing as a multidimensional structure. All addresses · in memory is essentially sequentially and 1D. If we want to represent a 2D ...
🌐
Sololearn
sololearn.com › en › Discuss › 2838429 › how-to-return-a-2d-array
Sololearn: Learn to Code
Sololearn is the world's largest community of people learning to code. With over 25 programming courses, choose from thousands of topics to learn how to code, brush up your programming knowledge, upskill your technical ability, or stay informed about the latest trends.
🌐
Thomas Cokelaer's Blog
thomas-cokelaer.info › blog › 2011 › 10 › allocation-2d-arrays-in-c-and-freeing-memory
Allocation 2D arrays in C (and freeing memory) | Thomas Cokelaer's blog
for (i = 0; i < nX; i++){ free(array[i]); } free(array); ... This entry was posted in Uncategorized and tagged malloc. Bookmark the permalink. ... Stan on python argparse issues with the help argument (TypeError: %o format: a number is required, not dict)
🌐
Learningc
learningc.org › chapters › chapter09-multi-dimensional-arrays › 2d-dynamic-memory-alloc
9.3. Dynamic Memory Allocation of 2D Arrays — Snefru: Learning Programming with C
We do not know the number of elements in an array before run-time, for example, the array size is taken as user input, or based on a calculation happening at run-time. It is better to allocate the array dynamically as this will allow us to check if the array was allocated or not on the heap. If heap does not have enough space, malloc returns NULL.
🌐
W3Schools
w3schools.com › c › c_arrays_multi.php
C Multidimensional Arrays (Two-dimensional and more)
Arrays can have any number of dimensions. In this chapter, we will introduce the most common; two-dimensional arrays (2D).
🌐
NVIDIA Developer Forums
forums.developer.nvidia.com › accelerated computing › cuda › cuda programming and performance
How to cudaMalloc two-dimensional array ? - CUDA Programming and Performance - NVIDIA Developer Forums
June 10, 2008 - May be a dumb question … however, I still can’t make it work :-) When allocationg something like this: int* pArray; cudaMalloc((void**)&pArray, 10 * sizeof(int)); everything works as expected. However, what should b…
Top answer
1 of 5
4

You say in the comments that n is the number of rows. So you need to allocate n rows each of length m. Therefore, the second for loop condition should be i < n. Also, you should check the return value of malloc for NULL in case it fails to allocate memory. I suggest the following change -

long long **a = malloc(n * sizeof(*a));
for (i = 0; i < n; i++) {
    a[i] = malloc(m * sizeof(*a[i]));
}

Please note that a multi-dimensional array is not a fundamentally new type. It's simply an array of elements where each element itself is an array (for a 2D array), an array of arrays (for a 3D) array and so on. If you are using C99, you can allocate your array cleanly and succinctly as

int nrow = 4;  // number of rows
int ncol = 8;  // number of columns

// define arr to be a pointer to an array of ncol ints, i.e.,
// arr is a pointer to an object of type (int[ncol])
int (*arr)[ncol] = malloc(sizeof(int[nrow][ncol]));

// check the result of malloc for NULL
if (arr == NULL) {
    printf("malloc failed to allocate memory\n");
    // handle it
}

// do stuff with arr
for (int i = 0; i < nrow; i++) {
    for (int j = 0; j < ncol; j++) {
        arr[i][j] = i + j;
    }
}
// after you are done with arr
free(arr);

You should also go through this - How do I work with dynamic multi-dimensional arrays in C?

2 of 5
1

You have three errors: The first is that you allocate only 5 secondary arrays, but in the input you loop over 6 of them.

The second problem is that array indices are zero-based, i.e. the index start at zero and goes to the size minus one.

The third problem is that you scan for two numbers (why?), but you provide only one destination pointer to scanf.

🌐
GitHub
gist.github.com › chris-sanders › 1196451
C 2D Array Malloc · GitHub
C 2D Array Malloc. GitHub Gist: instantly share code, notes, and snippets.
Top answer
1 of 4
10

Numpy C API

Your question is similar to this post.

You can use the function below to pass a C pointer to Numpy array. The memory will be freed automatically when the Numpy array is recycled. If you want free the pointer mamully, you should not set NPY_OWNDATA flag.

import numpy as np
cimport numpy as np

cdef pointer_to_numpy_array_complex128(void * ptr, np.npy_intp size):
    '''Convert c pointer to numpy array.
    The memory will be freed as soon as the ndarray is deallocated.
    '''
    cdef extern from "numpy/arrayobject.h":
        void PyArray_ENABLEFLAGS(np.ndarray arr, int flags)
    cdef np.ndarray[np.complex128, ndim=1] arr = \
            np.PyArray_SimpleNewFromData(1, &size, np.NPY_COMPLEX128, ptr)
    PyArray_ENABLEFLAGS(arr, np.NPY_OWNDATA)
    return arr

For reference:

  • PyArray_SimpleNewFromData
  • Numpy Data Type API

Cython Typed Memoryviews

Of couse, you can also use cython memoryview.

import numpy as np
cimport numpy as np

cdef np.complex128_t[:,:] view = <np.complex128_t[:n,:n]> c_pointer
numpy_arr = np.asarray(view)

The code above will transfer C pointer to a numpy array. However this would not free memory automaticlly, you have to free the memory by yourself or it would lead to memory leak!

2 of 4
1

A further option (in addition to the two options from the top answer: PyArray_SimpleNewFromData and just returning the typed memoryview without handling the memory) is to use the cython.view.array class.

This is a fairly low-level class that can be used to wrap existing memory. It has an attribute callback_free_data where you can set a function to be called on destruction so that it does free the memory (example code here is copied from the documentation):

cdef view.array my_array = view.array(..., mode="fortran", allocate_buffer=False)
my_array.data = <char *> my_data_pointer

# define a function that can deallocate the data (if needed)
my_array.callback_free_data = free

It exposes the buffer protocol so that you can index it, use it with typed memoryviews, or wrap it with a Numpy array (without copying) with np.asarray. The latter feature may be easier to use than PyArray_SimpleNewFromData.

🌐
Arduino Forum
forum.arduino.cc › projects › programming
Using malloc() and free() with 2D arrays in Arduino C - Programming - Arduino Forum
June 6, 2016 - I'm working on a project that involves uploading and storing a very compressed image file on an Arduino MKR1000 as a 2D array of bytes. I noticed that after uploading a couple images it stopped working, which I'm fairly certain is because I'm simply running out of memory.