dynamic array in c - c

I want after I do some calculation create an array in C would u please help me?
int len_arr = (sizeof inputs)/(sizeof inputs[0]);
int half_arr = len_arr / 2;
if(len_arr%2 != 0)
half_arr++;
int m[half_arr][half_arr];

I'm assuming you wish to create a matrix with row/column size of half_arr.
int i;
int len_arr = (sizeof inputs)/(sizeof inputs[0]);
int half_arr = len_arr / 2;
if(len_arr%2 != 0)
half_arr++;
int **m = malloc(half_arr * sizeof(int));
for (i = 0; i < half_arr; i++)
*m = malloc(half_arr * sizeof(int));
You should then be able to access m using m[row][column] or m[column][row].

You need to use malloc to allocate your 2-dimensional array.
Look at this LINK for a good explanation.
EDIT:
Starting from the code at the given link, I've written a piece of code that should work.
Some differences from James' code:
declaration of m at the top of the code block
conversion from the return type of malloc (void *) to the correct one
memory deallocation at the end
it's a complete code, that must work :P
#include <stdlib.h>
int main ()
{
// just an example of inputs...
int inputs[3][7];
// your code
int i;
int **m;
int len_arr = (sizeof inputs)/(sizeof inputs[0]);
int half_arr = len_arr / 2;
if(len_arr%2 != 0)
half_arr++;
// allocation of the array
m = (int **)malloc(half_arr * sizeof(int *));
for(i = 0; i < half_arr; i++)
m[i] = (int *)malloc(half_arr * sizeof(int));
// use the array as you like...
// ...
// let's release the allocated memory properly
for(i = 0; i < half_arr; i++)
free(m[i]);
free(m);
}

Your code is valid C99. You might want to use a compiler which supports newer revisions of the C language.
On Windows, I'd go with the MinGW edition of gcc. If you're stuck with MSVC, I suggest using C++ instead: the standard container types will make your life less painful.

Related

Problem with free() function in C and memory-leaks

I've a problem about deallocating memory using free() in C.
My program generates a random genealogic tree using a matrix. This matrix can be very huge depending on the number of family members. The program seemed to work fine until I decided to generate more than one tree. I noticed that generating about 100 trees causes my 8GB RAM to fill! I'm sure I can make a better code to reduce the demand of memory, but my problem remains.
I use free() to deallocate memory and there's no error. I installed Valgrind to se what's happening and it says that about 100 million byte per tree are definitely lost. This means that free() doesn't work fine. I don't now where is the problem. I link some functions that I think are correlated to the problem.
typedef struct{
int f_id;
char f_name[L_NAMES];
int generations;
int n_members;
type_people *members;
int_mtx *mtx;
}type_family;
The struct above is for the family.
typedef struct temp{
int p_id;
char name[L_NAMES];
char f_name[L_NAMES];
int generation;
int n_sons;
struct temp **sons;
int f_id;
int sex;
int age;
}type_people;
This is for the members.
typedef struct{
int i;
int j;
int **val;
}int_mtx;
And the matrix.
In the main i call the function to initialize the tree:
type_family *family_a;
family_a = malloc(sizeof(type_family));
family_a = init_family_n_gen(family_a, 6);
This is the frist part of init_family_n_gen():
type_family *init_family_n_gen(type_family *family, int n){
...
family->members = malloc(max_people * sizeof(type_people));
family->mtx = mtxcalloc(family->mtx, max_people, max_people - 1);
...
This code is for mtxcalloc that initializes the matrix:
int_mtx *mtxcalloc(int_mtx *mtx, int i, int j){
mtx = malloc(sizeof(int_mtx));
mtx->i = i;
mtx->j = j;
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
return mtx;
}
And to conclude the code to deallocate the family:
void free_family(type_family *family){
for(int m = 0; m < family->n_members; m++){
if(family->members[m].n_sons != 0){
free(family->members[m].sons);
}
}
mtxfree(family->mtx);
free(family->members);
}
And the one to deallocate the matrix:
void mtxfree(int_mtx *mtx){
for(int i = 0; i < mtx->i; i++){
free(mtx->val[i]);
}
free(mtx->val);
free(mtx);
}
Screen capture of Valgrind output
So I call the free_family(family_a) every time i need to regenerate the family but the memory still increases. (In the photo above the number of byte become 1 billion if i regenerate the family for 50 times).
Thanks for the support!
EDITED
I made a minimal reproducible example that emulates my original code. The structs and variables are the same but I changed the functions according to Weather Vane: they are all void and I pass them the double **.
The init_family_n_gen becomes:
void init_family(type_family **f){
type_family *family = malloc(sizeof(type_family));
family->members = malloc(100 * sizeof(type_people));
for(int m = 0; m < 100; m++){
family->members[m].n_sons = 0;
}
mtxcalloc(&family->mtx, 100, 99);
family->mtx->val[0][1] = 7;
family->mtx->val[9][8] = 1;
mtxrealloc(&family->mtx, 5, 4);
*f = family;
}
The main is:
type_family *family_a;
init_family(&family_a);
free_family(&family_a);
The only thing I added is this function(Is the code right?):
void mtxrealloc(int_mtx **mtx, int i, int j){
(*mtx)->i = i;
(*mtx)->j = j;
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
for(int a = 0; a < (*mtx)->i; a++){
(*mtx)->val[a] = realloc((*mtx)->val[a], (*mtx)->j * sizeof(int));
}
}
I noticed that the problem occours when i use the realloc function and i can't figure why. I link the images of Valgrind with and without the function mtxrealloc. (I see that there is aslo a 48 byte leak...).
Valgrind with realloc
Valgrind without realloc
Thanks again for your support!
This:
init_family(&family_a);
Causes this code from mtxcalloc to execute:
mtx->val = malloc(i * sizeof(int *));
for(int a = 0; a < i; a++){
mtx->val[a] = malloc(j * sizeof(int));
for(int b = 0; b < j; b++){
mtx->val[a][b] = 0;
}
}
, with i, j = 100, 99. That is, you allocate space for 100 pointers, and for each one, you allocate space for 99 ints. These are then accessible via family_a->mtx.
Very shortly thereafter, you make this call:
mtxrealloc(&family->mtx, 5, 4);
, which does this, among other things:
(*mtx)->val = realloc((*mtx)->val, (*mtx)->i * sizeof(int *));
That loses all the pointers (*mtx)->val[5] through (*mtx)->val[99], each of which is the sole pointer to allocated space sufficient for 99 ints. Overall, sufficient space for 9405 ints is leaked before you even perform any computations with the object you are preparing.
It is unclear why you overallocate, just to immediately (attempt to) free the excess, but perhaps that's an artifact of your code simplification. It would be much better to come up with a way to determine how much space you need in advance, and then allocate only that much in the first place. But if you do need to reallocate this particular data, then you need to first free each of the (*mtx)->val[x] that will be lost. Of course, if you were going to reallocate larger, then you would need to allocate / reallocate all of the (*mtx)->val[x].

Segmentation fault (core dumped) [Conway's game of life]

I'm working on a C implementation for Conway's game of life, I have been asked to use the following header:
#ifndef game_of_life_h
#define game_of_life_h
#include <stdio.h>
#include <stdlib.h>
// a structure containing a square board for the game and its size
typedef struct gol{
int **board;
size_t size;
} gol;
// dynamically creates a struct gol of size 20 and returns a pointer to it
gol* create_default_gol();
// creates dynamically a struct gol of a specified size and returns a pointer to it.
gol* create_gol(size_t size);
// destroy gol structures
void destroy_gol(gol* g);
// the board of 'g' is set to 'b'. You do not need to check if 'b' has a proper size and values
void set_pattern(gol* g, int** b);
// using rules of the game of life, the function sets next pattern to the g->board
void next_pattern(gol* g);
/* returns sum of all the neighbours of the cell g->board[i][j]. The function is an auxiliary
function and should be used in the following function. */
int neighbour_sum(gol* g, int i, int j);
// prints the current pattern of the g-board on the screen
void print(gol* g);
#endif
I have added the comments to help out with an explanation of what each bit is.
gol.board is a 2-level integer array, containing x and y coordinates, ie board[x][y], each coordinate can either be a 1 (alive) or 0 (dead).
This was all a bit of background information, I'm trying to write my first function create_default_gol() that will return a pointer to a gol instance, with a 20x20 board.
I then attempt to go through each coordinate through the 20x20 board and set it to 0, I am getting a Segmentation fault (core dumped) when running this program.
The below code is my c file containing the core code, and the main() function:
#include "game_of_life.h"
int main()
{
// Create a 20x20 game
gol* g_temp = create_default_gol();
int x,y;
for (x = 0; x < 20; x++)
{
for (y = 0; y < 20; y++)
{
g_temp->board[x][y] = 0;
}
}
free(g_temp);
}
// return a pointer to a 20x20 game of life
gol* create_default_gol()
{
gol* g_rtn = malloc(sizeof(*g_rtn) + (sizeof(int) * 20 * 20));
return g_rtn;
}
This is the first feature I'd like to implement, being able to generate a 20x20 board with 0's (dead) state for every coordinate.
Please feel free to criticise my code, I'm looking to determine why I'm getting the segmentation fault, and if I'm allocating memory properly in the create_default_gol() function.
Thanks!
The type int **board; means that board must contain an array of pointers, each of which points to the start of each row. Your existing allocation omits this, and just allocates *g_rtn plus the ints in the board.
The canonical way to allocate your board, supposing that you must stick to the type int **board;, is:
gol* g_rtn = malloc(sizeof *g_rtn);
g_rtn->size = size;
g_rtn->board = malloc(size * sizeof *g_rtn->board);
for (int i = 0; i < size; ++i)
g_rtn->board[i] = malloc(size * sizeof **g_rtn->board);
This code involves a lot of small malloc chunks. You could condense the board rows and columns into a single allocation, but then you also need to set up pointers to the start of each row, because board must be an array of pointers to int.
Another issue with this approach is alignment. It's guaranteed that a malloc result is aligned for any type; however it is possible that int has stricter alignment requirements than int *. My following code assumes that it doesn't; if you want to be portable then you could add in some compile-time checks (or run it and see if it aborts!).
The amount of memory required is the sum of the last two mallocs:
g_rtn->board = malloc( size * size * sizeof **g_rtn->board
+ size * sizeof *g_rtn->board );
Then the first row will start after the end of the row-pointers (a cast is necessary because we are converting int ** to int *, and using void * means we don't have to repeat the word int):
g_rtn->board[0] = (void *) (g_rtn->board + size);
And the other rows each have size ints in them:
for (int i = 1; i < size; ++i)
g_rtn->board[i] = g_rtn->board[i-1] + size;
Note that this is a whole lot more complicated than just using a 1-D array and doing arithmetic for the offsets, but it was stipulated that you must have two levels of indirection to access the board.
Also this is more complicated than the "canonical" version. In this version we are trading code complexity for the benefit of having a reduced number of mallocs. If your program typically only allocates one board, or a small number of boards, then perhaps this trade-off is not worth it and the canonical version would give you fewer headaches.
Finally - it would be possible to allocate both *g_rtn and the board in the single malloc, as you attempted to do in your question. However my advice (based on experience) is that it is simpler to keep the board separate. It makes your code clearer, and your object easier to use and make changes to, if the board is a separate allocation to the game object.
create_default_gol() misses to initialise board, so applying the [] operator to it (in main() ) the program accesses "invaid" memory and with ethis provokes undefined behaviour.
Although enough memory is allocated, the code still needs to make board point to the memory by doing
gol->board = ((char*) gol) + sizeof(*gol);
Update
As pointed out by Matt McNabb's comment board points to an array of pointers to int, so initialisation is more complicate:
gol * g_rtn = malloc(sizeof(*g_rtn) + 20 * sizeof(*gol->board));
g_rtn->board = ((char*) gol) + sizeof(*gol);
for (size_t i = 0; i<20; ++i)
{
g_rtn->board[i] = malloc(20 * sizeof(*g_rtn->board[i])
}
Also the code misses to set gol's member size. From what you tell us it is not clear whether it shall hold the nuber of bytes, rows/columns or fields.
Also^2 coding "magic numbers" like 20 is bad habit.
Also^3 create_default_gol does not specify any parameters, which explictily allows any numberm and not none as you might perhaps have expected.
All in all I'd code create_default_gol() like this:
gol * create_default_gol(const size_t rows, const size_t columns)
{
size_t size_rows = rows * sizeof(*g_rtn->board));
size_t size_column = columns * sizeof(**g_rtn->board));
gol * g_rtn = malloc(sizeof(*g_rtn) + size_rows);
g_rtn->board = ((char*) gol) + sizeof(*gol);
if (NULL ! = g_rtn)
{
for (size_t i = 0; i<columns; ++i)
{
g_rtn->board[i] = malloc(size_columns); /* TODO: Add error checking here. */
}
g_rtn->size = size_rows * size_columns; /* Or what ever this attribute is meant for. */
}
return g_rtn;
}
gol* create_default_gol()
{
int **a,i;
a = (int**)malloc(20 * sizeof(int *));
for (i = 0; i < 20; i++)
a[i] = (int*)malloc(20 * sizeof(int));
gol* g_rtn = (gol*)malloc(sizeof(*g_rtn));
g_rtn->board = a;
return g_rtn;
}
int main()
{
// Create a 20x20 game
gol* g_temp = create_default_gol();
int x,y;
for (x = 0; x < 20; x++)
{
for (y = 0; y < 20; y++)
{
g_temp->board[x][y] = 10;
}
}
for(x=0;x<20;x++)
free(g_temp->board[x]);
free(g_temp->board);
free(g_temp);
}
main (void)
{
gol* gameOfLife;
gameOfLife = create_default_gol();
free(gameOfLife);
}
gol* create_default_gol()
{
int size = 20;
gol* g_rtn = malloc(sizeof *g_rtn);
g_rtn = malloc(sizeof g_rtn);
g_rtn->size = size;
g_rtn->board = malloc(size * sizeof *g_rtn->board);
int i, b;
for (i = 0; i < size; ++i){
g_rtn->board[i] = malloc(sizeof (int) * size);
for(b=0;b<size;b++){
g_rtn->board[i][b] = 0;
}
}
return g_rtn;
}
Alternatively, since you also need to add a create_gol(size_t new_size) of custom size, you could also write it as the following.
main (void)
{
gol* gameOfLife;
gameOfLife = create_default_gol();
free(gameOfLife);
}
gol* create_default_gol()
{
size_t size = 20;
return create_gol(size);
}
gol* create_gol(size_t new_size)
{
gol* g_rtn = malloc(sizeof *g_rtn);
g_rtn = malloc(sizeof g_rtn);
g_rtn->size = new_size;
g_rtn->board = malloc(size * sizeof *g_rtn->board);
int i, b;
for (i = 0; i < size; ++i){
g_rtn->board[i] = malloc(sizeof (int) * size);
for(b=0;b<size;b++){
g_rtn->board[i][b] = 0;
}
}
return g_rtn;
}
Doing this just minimizes the amount of code needed.

Dynamically allocated 2 dimensional array

I am trying to build two dimensional array by dynamically allocating. My question is that is it possible that its first dimension would take 100 values, then second dimension would take variable amount of values depending on my problem? If it is possible then how I would access it? How would I know the second dimension's boundary?
(See the comments in the code)
As a result you'll get an array such like the following:
// Create an array that will contain required variables of the required values
// which will help you to make each row of it's own lenght.
arrOfLengthOfRows[NUMBER_OF_ROWS] = {value_1, value_2, ..., value_theLast};
int **array;
array = malloc(N * sizeof(int *)); // `N` is the number of rows, as on the pic.
/*
if(array == NULL) {
printf("There is not enough memory.\n");
exit (EXIT_FAILURE);
}
*/
// Here we make each row of it's own, individual length.
for(i = 0; i < N; i++) {
array[i] = malloc(arrOfLengthOfRows[i] * sizeof(int));
/*
if(array[i] == NULL) {
printf("There is not enough memory.\n");
exit (EXIT_FAILURE);
}
*/
}
You can use array of 100 pointers:
int *arr[100];
then you can dynamically allocate memory to each of the 100 pointers separately of any size you want, however you have to remember how much memory (for each pointer) you have allocated, you cannot expect C compiler to remember it or tell it to you, i.e. sizeof will not work here.
To access any (allowed, within boundary) location you can simply use 2D array notation e.g. to access 5th location of memory allocated to 20th pointer you can use arr[20][5] or *(arr[20] + 5).
I believe the OP wants a single chunk of memory for the array, and is willing to fix one of the dimensions to get it. I frequently like to do this when coding in C as well.
We all used to be able to do double x[4][]; and the compiler would know what to do. But someone has apparently messed that up - maybe even for a good reason.
The following however still works and allows us to use large chunks of memory instead of having to do a lot of pointer management.
#include <stdio.h>
#include <stdlib.h>
// double x[4][];
struct foo {
double y[4];
} * x;
void
main(int ac, char * av[])
{
double * dp;
int max_x = 10;
int i;
x = calloc(max_x, sizeof(struct foo));
x[0].y[0] = 0.23;
x[0].y[1] = 0.45;
x[9].y[0] = 1.23;
x[9].y[1] = 1.45;
dp = x[9].y;
for (i = 0; i < 4; i++)
if (dp[i] > 0)
printf("%f\n", dp[i]);
}
The trick is to declare the fixed dimension in a struct. But keep in mind that the "first" dimension is the dynamic dimension and the "second" one is fixed. And this is the opposite of the old way ...
You will have to track the size of your dynamic dimension on your own - sizeof can't help you with that.
Using anonymous thingies you might even be able to git rid of 'y'.
Using a single pointer:
int *arr = (int *)malloc(r * c * sizeof(int));
/* how to access array elements */
for (i = 0; i < r; i++)
for (j = 0; j < c; j++)
*(arr + i*c + j) = ++count; //count initialized as, int count=0;
Using pointer to a pointer:
int **arr = (int **)malloc(r * sizeof(int *));
for (i=0; i<r; i++)
arr[i] = (int *)malloc(c * sizeof(int));
In this case you can access array elements same as you access statically allocated array.

How to assign anything to array in this C function?

I have this C function:
fill_array(&data, &size);
void fill_array(int **data, int *size){
printf("Size is:");
scanf("%d", size);
*data = malloc(*size * sizeof(int *));
int i = 0;
for (i = 0; i < size; i++){
(*data)[i] = rand() % 11;
}
}
I want to assign data[i] for example, to random number. How to do such a thing? I have tried many variations, but all of the time my program crashes.
Thanks.
*data = malloc(*size * sizeof(**data));
(*data)[5] = 15;
Refer to cdecl web site.
Do not cast malloc
Edit according to the question edit
the for loop contains typo
for (i = 0; i < size; i++)
it should be
for (i = 0; i < *size; i++)
you can use (*data)[5] = 15; instead of this *data[5] = 15; Because precedence of [] greater than precedence of *..
As others said, you need to put parentheses to get the operator precedence right. If you want to use the "array" a lot, it might make sense to create a temporary variable that is easy to use:
int *p;
...
*data = malloc(*size * sizeof **data);
p = *data;
And then you could use p[5] etc.
Good program design dictates that we should keep memory allocation and the actual algorithm separated. To have a function that takes user input and allocates memory and performs some algorithm is probably not the optimal program design.
So the proper solution is not to patch that function to make it work, but instead to make some new ones:
int get_size_from_user (void)
{
int size;
printf("Size is:");
scanf("%d", &size);
return size;
}
bool alloc_array (int** array, int size)
{
*array = malloc(size * sizeof(int));
return *array != NULL;
}
void fill_array (int* array, int size)
{
// ...whatever you want to do here
data[5] = 15;
}
And look at that, the need for obscure syntax disappeared as soon as we improved the program design! Coincidence?

How to declare pointer and allocate memory a two-dimensional array and pass to a function

I want to declare the correct pointer and allocate memory for a two-dimensional array, and correctly pass to a function. I am having trouble getting this to work properly and need help.
Here is my code:
double **podrucje;
podrucje=(double **) malloc (sizeof (double *) *123);
for (i=0;i<(123);i++)
{
podrucje[i]=(double *) malloc (sizeof (double) * 11);
}
for (i=0;i<(123);i++)
{
memset (podrucje[i], 0, 10);
}
But this code doesnt work, it messes up whole my program. So i decided to give up on dynamic allocation and use this:
double podrucje[123][11]={0};
But i dont know how to send it and use it in function...
memset works on per byte basis.
double **podrucje = (double **) malloc (sizeof (double *) * 123);
for (i = 0; i < 123; i++)
{
podrucje[i] = (double *) malloc (sizeof (double) * 11);
memset(podrucje[i], 0, sizeof(double) * 11);
}
if you want to pass it just declare it as such
void function(double podrucje[123][11]) {
...
}
You're best off to use malloc, but allocate the whole array on your second line, so it all gets allocated in contiguous memory. So
podrucje = (double*) malloc (sizeof (double) * 123 * 11);
Then the first loop can go away too. And it looks like you're initializing the array to 0 -- in that case, use calloc instead of malloc, eliminating the second loop.
To index into the array, use things like
double myitem = podrucje [11 * row + col];
You should of course use a define or similar to keep the use of 11 consistent, but that's not the point of this answer.
Write the function argument the same way you wrote the variable definition:
void myfunc(double podrucje[123][11])
{
...
}
double podrucje[123][11];
myfunc(podrucje);
Note that the array is passed "by reference" rather than being copied.
In the following code snippet,
podrucje[i]=(double *) malloc (sizeof (double) * 11);
for (i=0;i<(123);i++)
{
memset (podrucje[i], 0, 10);
}
1) You dont need the extra parenthesis against the numbers 123 and 11
The for loop can be as follows,
for (i = 0; i < 123; i++)
2) Instead of using 123 and 11. Try to define a MACRO and use that instead.
Advantage: The code becomes independent of special numbers and is easily maintainable. Especially in the cases of larger code base.
3) If you read the code, podrucje[i] is allocated a memory of 11 doubles But when you memset you are setting it for only 10 doubles while the last one may or may not consist of garbage. Use calloc here, It not only allocated memory but also initializes the same.
podrucje[i]=(double *) calloc(11,sizeof(double));
Also It could be more helpful if you could tell How exactly is it screwing up your code ?
Example, Code Snippet could help more than just stating its screwing up.
It helps others to investigate and solve the issue.
If you have a modern C compiler (C99 would do) you can even declare real 2D matrices with variable sizes. You don't need to fall back to this awful emulation with pointers.
void myfunc(size_t n, size_t m, double podrucje[n][m])
{
...
}
double (*podrucje)[n] = malloc(sizeof(double[n][m]));
myfunc(n, m, podrucje);
For the function you just have to ensure that the declarations of n and m come first, before the matrix.
There are several ways to dynamically allocate memory for an NxM array. Here are two:
You can declare a pointer to an M-element array, and then malloc N instances of it:
double (*podrucje)[11] = malloc(sizeof *podrucje * 123);
As of C89, you don't need to cast the result of malloc, and the practice is discouraged. Also, note that the operand to sizeof is the expression *podrucje; this gives me the same result as sizeof (double) * 11.
You would index this array as podrucje[i][j] like any other 2D array. podrucje[i] implicitly dereferences the pointer (remember that a[i] is equivalent to *(a + i)) so you don't have to do anything funky with it.
You would use it in a function as follows:
void init(double (*podrucje)[11], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < 11; j++)
podrucje[i][j] = 0.0;
}
which would be called as
init(podrucje, 123);
The drawback to this method is that the function can only operate on Nx11 arrays; if you're using a C99 compiler or a C2011 compiler that supports variable length arrays, you could specify the number of columns as a runtime variable:
void foo(void)
{
size_t rows = 123, cols = 11;
double (*podrucje)[cols] = malloc(sizeof *podrucje * rows);
if (podrucje)
init(cols, podrucje, rows);
...
}
// cols must be declared before it can be used
// in an array declarator
//
void init(size_t cols, double(*podrucje)[cols], size_t rows)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
podrucje[i][j] = 0.0;
}
When you're done with the array, deallocate it as follows:
free(podrucje);
The other approach is to allocate each row separately, as follows:
size_t rows = 123, cols = 11;
double **podrucje = malloc(sizeof *podrucje * rows);
if (!podrucje)
{
// malloc failed; handle allocation error here
}
else
{
size_t i;
for (i = 0; i < rows; i++)
{
podrucje[i] = malloc(sizeof *podrucje[i] * cols);
if (!podrucje[i])
{
// malloc failed; handle allocation error here
}
}
}
And you would use it in a function as follows:
void foo()
{
double **podrucje;
// allocate array as above
init(foo, rows, cols);
...
}
void init(double **podrucje, size_t rows, size_t cols)
{
size_t i, j;
for (i = 0; i < rows; i++)
for (j = 0; j < cols; j++)
podrucje[i][j] = 0.0;
}
When you're finished with the array, deallocate it as follows:
for(i = 0; i < rows; i++)
free(podrucje[i]);
free(podrucje);
The first method allocates memory as a single, contiguous block; the second allocates it in a series of smaller, discontinuous chunks. If your array is especially big or your heap especially fragmented, the first method may fail where the second will succeed. If you're working with a compiler that doesn't support variable-length arrays, the first method is much less flexible, because the number of columns must be specified at compile time.
How could the same indexing method work for both forms?
In the first case, each podrucje[i] is an 11-element array of double; indexing it with j works like any other array. In the second case, each podrucje[i] is a pointer to double. Since a[i] is evaluated as *(a + i), array indexing works on pointer expressions just as well as array expressions.
int print_func(char((*p)[26])[10])
{
int i = 0;
for (i=0; i < 26 ; i++) {
fprintf(stderr, "%02d:%.*s\n", i, 10, p[0][i]);
}
return (0);
}
int main(void)
{
int nrow = 26;
int ncol = 10;
char((*p)[26])[10] = (char((*)[26])[10])(0);
char(*q)[10];
char c = 'a';
int i = 0;
p = (char((*)[26])[10])malloc(sizeof(char) * nrow * ncol);
if ((char((*)[26])[10])0 == p) {
return (-1);
}
for (i=0, q=p[0]; i < nrow ; i++) {
memset(q, c, sizeof(char) * ncol);
c++;
q++;
}
for (i=0,q=p[0] ; i < nrow ; i++) {
fprintf(stderr, "%.*s\n", 10, q);
q++;
}
p[0][8][0]='z';
getchar();
print_func(p);
return (0);
}

Resources