How do you use malloc to allocate memory for a multidimensional array?
For example, you would like to use arr[6][9].
You may have tried the following:
// Warning: broken example
int **arr = malloc(50 * sizeof(int));
arr[6][9] = 42; // dangerous! Segmentation fault (core dumped)
This is obviously wrong. But what is the correct way to allocate (and free) memory for multidimensional arrays?
The most basic multidimensional array is of course the 2D-array.
It has two dimensions, in this example I'll use an array of size x by y.
For simplicity I used the integer type to store data. The storage type is not relevant to the general technique to use.
Any error checking is skipped in the first few examples, for clarity.
Later examples include some basic forms of error checking.
The size_t type is used for index offsets, to avoid confusion with the type (integer) stored in the multidimensional array.
Basic 2D example
/*
* Warning: no error checks!
*/
int **create_2d(size_t x, size_t y)
{
int *values = malloc(x * y * sizeof *values);
int **index_x = malloc(x * sizeof *index_x);
for (size_t i = 0; i < x; i++)
index_x[i] = &values[i * y];
return index_x;
}
You can now read and write all locations within the 2D-array using as long as you don't go below 0 or over x and y as that would be accessing the array out-of-bounds.
int **arr = create_2d[20][24];
arr[6][9] = 42; // perfectly fine!
Maybe you are satisfied with this code, and you copy/paste this into your project.
That is completely fine, yet at your own risk. I'll provide further explanation and some words of warning.
Some explanation of what this all means. In the end the multidimensional array needs to store x rows and y columns of type int. This means that the required storage size is x * y * sizeof(int) at the very least.
In this example all of that required storage is allocated in a single go. However instead of sizeof(int) is used sizeof *values, since that is easier to maintain, should e.g. the storage type change. It is less error prone this way.
Now, all of the memory is "contiguous", and accessible as an offset from values[0] to values[x * y]. This is actually often already usable as a faux 2-dimensional array by using some simple arithmetic. For example, you could say that index (i,j) is already accessible via values[i * y + j];. The first y values are row 0, the next y values are row 1, etc.
To make it truely accessible via index [i][j] that index needs to actually be allocated as well. In this case I called it index_x. It will have to be able to point to x different memory locations, specifically the "first" y value every "row".
Often times you will see people perform the allocation in a loop. That is actually not necessary and makes things a bit more complicated in terms of error checking and deallocation. Nonetheless, assigning the memory locations for the start of the y-rows needs to be done in a loop, where I used i as an iterator value to range from 0 to x. Because index_x needs to point to pointers, we put the address of values[i * y] in the index_x.
It should be noted that it is also index_x that is returned, not values. If you would in fact need to access values, that can still be done via index_x[0]. This will be handy when we need to free the memory.
Basic freeing 2D example
The following function will free up the allocated memory:
/*
* Warning: no error checks!
*/
void destroy_2d(int **ptr)
{
free(ptr[0]);
free(ptr);
}
As you can see, no loops are required here.
Now it may not be apparent why with is preferable over using malloc within the loop. It should become apparent once you start adding error-checking code, or when you need to allocate a lot of items or have a lot of nesting. The same principle applies to a 3-dimensional array. Let me demonstrate the 3D array for clarity:
Basic 3D example
int ***create_3d(size_t x, size_t y, size_t z)
{
int *values = malloc(x * y * z * sizeof *values);
int **index_y = malloc(x * y * sizeof *index_y);
int ***index_x = malloc(x * sizeof *index_x);
for (size_t i = 0; i < x; i++) {
index_x[i] = &index_y[i * y];
for (size_t j = 0; j < y; j++) {
// remove ONE of the following two lines
index_x[i][j] = &values[(i * y + j) * z]; // or, alternatively:
index_y[i * y + j] = &values[(i * y + j) * z]; // this is exactly the same
}
}
return index_x;
}
void destroy_3d(int ***ptr)
{
free(ptr[0][0]);
free(ptr[0]);
free(ptr);
}
This is the same principle, albeit with a bit more complex arithmetic.
Let me show you why this matters by adding very basic error checking:
Basic 3D examples w/ error checking
int ***create_3d_e(size_t x, size_t y, size_t z)
{
int *values = malloc(x * y * z * sizeof *values);
if (!values)
return NULL;
int **index_y = malloc(x * y * sizeof *index_y);
if (!index_y) {
free(values);
return NULL;
}
int ***index_x = malloc(x * sizeof *index_x);
if (!index_x) {
free(index_y);
free(values);
return NULL;
}
for (size_t i = 0; i < x; i++) {
index_x[i] = &index_y[i * y];
for (size_t j = 0; j < y; j++) {
index_y[i * y + j] = &values[(i * y + j) * z];
}
}
return index_x;
}
Or, alternatively, if you prefer a different code style:
int ***create_3d_g(size_t x, size_t y, size_t z)
{
int *values;
int **index_y;
int ***index_x;
size_t i, j;
values = malloc(x * y * z * sizeof *values);
if (!values)
goto err;
index_y = malloc(x * y * sizeof *index_y);
if (!index_y)
goto err_y;
index_x = malloc(x * sizeof *index_x);
if (!index_x)
goto err_x;
for (i = 0; i < x; i++) {
index_x[i] = &index_y[i * y];
for (j = 0; j < y; j++) {
index_y[i * y + j] = &values[(i * y + j) * z];
}
}
return index_x;
err_x:
free(index);
err_y:
free(values);
err:
return NULL;
}
And then some basic error preventing logic when freeing:
Basic freeing 3D example w/ error checking
void destroy_3d_e(int ***ptr)
{
if (ptr) {
if (ptr[0]) {
free(ptr[0][0]);
free(ptr[0]);
}
free(ptr);
}
}
This is another advantage of not allocating memory within the loop! In that case, the "destroy" function should also know about the dimensions and free all allocations in a loop. Added complexity when some allocation fails halfway in a loop of a nested multidimensional array. Crashing your program is not always an option, you might want or need to deallocate the memory to prevent nasty bugs. That is when the freeing of "contiguous" memory is so much easier than the "loop-malloc" method. I didn't provide example for that, because I don't think that will be helpful. If other people want to provide that as a separate answer, please do so, with the appropriate reservations.
As an exercise for the reader: try to implement that for a 3-dimensional array. Checking for failure halfway of building up the array, and gracefully tearing everything down without memory leaks.
HEAP SUMMARY:
in use at exit: 0 bytes in 0 blocks
total heap usage: 3 allocs, 3 frees, 96,481,600 bytes allocated
All heap blocks were freed -- no leaks are possible
ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
I hope to see far fewer people asking for that method in the future. And I hope these examples provided you with a better understanding of the internal workings of multidimensional arrays.
Related
I wrote a C code that usea a matrix of double:
double y[LENGTH][4];
whith LENGTH=200000 I have no problem.
I have to increase the numbers of rows to LENGTH=1000000 but when I enter this value and execute the program it returns me segmentation fault.
I tried to allocate more memory using malloc:
double **y = (double **)malloc(LENGTH * sizeof(double*));
for(int i = 0; i < LENGTH; i++){
y[i] = (double *)malloc(4 * sizeof(double));
}
I run the the code above and after some second of calculations it still gives me "segmentation fault".
Could anyone help me?
If you want a dynamic allocated 2D array of the specified row-width, just do this:
double (*y)[4] = malloc(LENGTH * sizeof(*y));
There is no need to malloc each row in the matrix. A single malloc and free will suffice. Only if you need dynamic row width (each row can vary in width independent of others) or the column count is arbitrary should a nested malloc loop be considered. Neither appears to be your case here.
Notes:
Don't cast malloc in C programs
Be sure to free(y); when finished with this little tryst.
The reason your statically allocated array is segfaulting with a million elements is (presumably) because it's being allocated on the stack. To have your program have a larger stack, pass appropriate switches to your compiler.
ProTip: You will experience less memory fragmentation and better performance if you flip your loop around, allocating
(double *)malloc(LENGTH * sizeof(double));
four times. This will require changing the order of your indices.
I ran the the code with this definition and after some second of calculations it still gives me "segmentatin fault"
If you're getting a segmentation fault after allocating the memory, you're writing outside of your memory bounds.
I run this code
#include <stdio.h>
#include <stdlib.h>
// We return the pointer
int **get(int N, int M) /* Allocate the array */
{
/* Check if allocation succeeded. (check for NULL pointer) */
int i, **table;
table = malloc(N*sizeof(int *));
for(i = 0 ; i < N ; i++)
table[i] = malloc( M*sizeof(int) );
return table;
}
void free2Darray(int** p, int N) {
int i;
for(i = 0 ; i < N ; i++)
free(p[i]);
free(p);
}
int main(void)
{
const int LENGTH = 1000000;
int **p;
p = get(LENGTH, 4);
printf("ok\n");
free2Darray(p ,LENGTH);
printf("exiting ok\n");
return 0;
}
and it was executed normally.
I got the code from my pseudo-site.
You should not cast what malloc returns. Why?
Also notice, that since you need a dynamic allocation only for the number of rows, since you know the number of columns. So, you can modify the code yourself (so that you have some fun too. :) )
I hope you didn't forget to **free** your memory.
In my C code I am allocating memory for 2d array double E[2000][2000]; but when I run it gets a runtime error Segmentation fault(core dumped) and when I reduce the array size to somewhere around 900 then the code runs fine.
Why it is showing runtime error since double take 64 bits memory (IEEE standard) so the code should take approximately 32MB which is not much compared to the ram size.And if it is not supported in C then how should I proceed if my maximum number of data that I have to store is 4000000 each are floating point numbers.
Are you declaring E as a local variable ? If so, you're running out of stack memory.
void func()
{
double E[2000][2000]; /// definitely an overflow
}
Use dynamic allocation:
double* E = malloc(2000 * 2000 * sizeof(double));
/// don't forget to "free(E);" later
Or if you need the 2D array, use a zig-zag:
double** E = malloc(2000 * sizeof(double*));
/* check that the memory is allocated */
if(!E)
{
/* do something like exit(some_error_code); to terminate your program*/
}
for(i = 0 ; i < 2000 ; i)
{
E[i] = malloc(2000 * sizeof(double));
/* check that the memory for this row is allocated */
if(!E[i])
{
/* do something like exit(some_error_code); to terminate your program*/
}
}
Then the deallocation is a little more complicated:
for(i = 0 ; i < 2000 ; i)
{
free(E[i]);
}
free(E);
P.S. If you want to keep all of you data in a continuous way, there's a trick (code from Takuya Ooura's FFT Package)
double **alloc_2d(int n1, int n2)
{
double **ii, *i;
int j;
/* pointers to rows */
ii = (double **) malloc(sizeof(double *) * n1);
/* some error checking */
alloc_error_check(ii);
/* one big memory block */
i = (double *) malloc(sizeof(double) * n1 * n2);
/* some error checking */
alloc_error_check(i);
ii[0] = i;
for (j = 1; j < n1; j++) {
ii[j] = ii[j - 1] + n2;
}
return ii;
}
void free_2d(double **ii)
{
free(ii[0]);
free(ii);
}
The you just call
double** E = alloc2d(2000, 2000);
and
free_2d(E);
I assume you are allocating it on the stack by simply
double E[2000][2000];
which will probably be more than stack size allocated to your program.
Try using malloc (or new in c++) or increase the default stack size of your program using options. gcc can be configured using setrlimit() for this purpose.
setting stack size in gcc
Keep in mind that even if stack size is increased, an array of this size should be global
You can also use a single statement to allocate a 2D array on heap if one dimension is fixed in size
double (* E)[COLUMN_SIZE];
int rows = 20; // this is dynamic and can be input from user at run time
E = malloc(rows * sizeof(*E)); // this needs to be freed latter
A more detailed similar example
allocating 2d array without loops
It depends on where you allocate the array. Using stack space will probably cause an overflow (unless you get the linker to allocate an extra large stack).
For example, this might not work
int main()
{
double E[2000][2000]; // Likely an overflow
}
However, moving the array to the static memory area
double E[2000][2000];
int main()
{
// use E here
}
will probably avoid the problem.
I am generating contiguous 2d arrays using the method posted on here by Shawn Chin.[1][2] It works very well.
Briefly from his post:
char** allocate2Dchar(int count_x, int count_y) {
int i;
# allocate space for actual data
char *data = malloc(sizeof(char) * count_x * count_y);
# create array or pointers to first elem in each 2D row
char **ptr_array = malloc(sizeof(char*) * count_x);
for (i = 0; i < count_x; i++) {
ptr_array[i] = data + (i*count_y);
}
return ptr_array;
}
And the following free function:
void free2Dchar(char** ptr_array) {
if (!ptr_array) return;
if (ptr_array[0]) free(ptr_array[0]);
free(ptr_array);
}
It is not obvious to me how to create an equivalent reallocate function in either dimension, though I am only interested in realloc'ing the number of rows while maintaining continuity. Growing the number of columns would be interesting to understand but probably quite difficult. I haven't found any direct discussion of this issue anywhere other than to say, "it's hard!".[2]
Of course this is doable by a horrible brute force method, copying the data to a new 1D array (data, above) for storage, realloc'ing the 1D array, then freeing and regenerating the pointers (ptr_array) to the row elements for the new size. This, however, is pretty slow for row modifications, since it is necessary to at least double the memory requirement to copy out the data, and this is truly horribly bad for changing the number of columns.
This is an example of said method for changing the number of rows (it wouldn't work properly for changing the number of columns because the offsets for the pointers would be wrong for the data). I haven't fully tested this, but you get the idea ...
double **
reallocate_double_array (double **ptr_array, int count_row_old, int count_row_new, int count_col)
{
int i;
int old_size = count_row_old * count_col;
int new_size = count_row_new * count_col;
double *data = malloc (old_size * sizeof (double));
memcpy (&data[0], &ptr_array[0][0], old_size * sizeof (double));
data = realloc (data, new_size * sizeof (double));
free (ptr_array[0]);
free (ptr_array);
ptr_array = malloc (count_row_new, sizeof (double *));
for (i = 0; i < count_row_new; i++)
ptr_array[i] = data + (i * count_col);
return ptr_array;
}
Plus, this method requires you know the previous size, which is obnoxious!
Any thoughts greatly appreciated.
[1] How can I allocate a 2D array using double pointers?
[2] http://www.eng.cam.ac.uk/help/tpl/languages/C/teaching_C/node52.html
The first malloc and the memcpy are unnecessary, because you have easy access to the original data array at ptr_array[0]. You don't need to know the old size, because realloc should recall how much it allocated at the address and move the correct ammount of data.
Something like this should work.
double **
reallocate_double_array (double **ptr_array, int count_row_new, int count_col)
{
int i;
int new_size = count_row_new * count_col;
double *data = ptr_array[0];
data = realloc (data, new_size * sizeof (double));
free (ptr_array);
ptr_array = calloc (count_row_new, sizeof (double *));
for (i = 0; i < count_row_new; i++)
ptr_array[i] = data + (i * count_col);
return ptr_array;
}
I am given the following structures to create my code with:
struct Mtrx {
unsigned double h;
struct MtrxRows** mtrxrows;
}
struct MtrxRows {
unsigned double w;
double* row;
}
I am trying to create a method called mtrxCreate that takes in parameters height and width and this is what I have below:
Mtrx* mtrxCreate(unsigned double height, unsigned double width){
Mtrx* mtrx_ptr = malloc(sizeof(double)*height);
int i;
mtrx_ptr->mtrxrows = malloc(sizeof(double)*height);
for(i = 0; i < height; ++i){
mtrx_ptr->mtrxrows[i]->row = malloc(sizeof(double) * width);
mtrx_ptr->mtrxrows[i]->w = width;
}
mtrx_ptr->h = height;
return mtrx_ptr;
}
The GCC compiler is telling me that I have a segmentation fault so I believe I did not allocate the memory correctly. I am not sure what memory I am still needing to allocating and if I allocated the current amount to the parts of the matrix above, any help is appreciated!
You aren't allocating the right amount of memory for certain things. First of all, the Mtrx structure itself:
Mtrx* mtrx_ptr = malloc(sizeof(double)*height);
Should be:
Mtrx* mtrx_ptr = malloc(sizeof(struct Mtrx));
Next, I'm not sure why your mtrxrows field is a double pointer. I think it should be a single pointer, a one-dimensional array of rows (where each row has some number of elements in it, as well). If you change it to a single pointer, you would allocate the rows as such:
mtrx_ptr->mtrxrows = malloc(sizeof(struct MtrxRows)*height);
Edit: Sorry I keep noticing things in this sample, so I've tweaked the answer a bit.
Wow. I don't exactly know where to start with cleaning that up, so I'm going to try to start from scratch.
From your code, it seems like you want all rows and all columns to be the same size - that is, no two rows will have different sizes. If this is wrong, let me know, but it's much harder to do.
Now then, first let's define a struct to hold the number of rows, the number of columns, and the array data itself.
struct Matrix {
size_t width;
size_t height;
double **data;
};
There are different ways to do store the data, but we can look at those later.
size_t is an unsigned integer (not floating point - there are no unsigned floating point types) type defined in stddef.h (among other places) to be large enough to store any valid object size or array index. Since we need to store array sizes, it's exactly what we need to store the height and width of our matrix.
double **data is a pointer to a pointer to a double, which is (in this case) a complex way to say a two-dimensional array of doubles that we allocate at runtime with malloc.
Let's begin defining a function. All these lines of code go together, but I'm splitting them up to make sure you understand all the different parts.
struct Matrix *make_Matrix(size_t width, size_t height, double fill)
Notice that you have to say struct Matrix, not just Matrix. If you want to drop the struct you'd have to use a typedef, but it's not that important IMHO. The fill parameter will allow the user to specify a default value for all the elements of the matrix.
{
struct Matrix *m = malloc(sizeof(struct Matrix));
if(m == NULL) return NULL;
This line allocates enough memory to store a struct Matrix. If it couldn't allocate any memory, we return NULL.
m->height = height;
m->width = width;
m->data = malloc(sizeof(double *) * height);
if(m->data == NULL)
{
free(m);
return NULL;
}
All that should make sense. Since m->data is a double **, it points to double *s, so we have to allocate a number of double *-sized objects to store in it. If we want it to be our array height, we allocate height number of double *s, that is, sizeof(double *) * height. Remember: if your pointer is a T *, you need to allocate T-sized objects.
If the allocation fails, we can't just return NULL - that would leak memory! We have to free our previously allocated but incomplete matrix before we return NULL.
for(size_t i = 0; i < height; i++)
{
m->data[i] = malloc(sizeof(double) * width);
if(m->data[i] == NULL)
{
for(size_t j = 0; j < i; j++) free(m->data[j]);
free(m->data);
free(m);
return 0;
}
Now we're looping over every column and allocating a row. Notice we allocate sizeof(double) * width space - since m->data[i] is a double * (we've dereferenced the double ** once), we have to allocate doubles to store in that pointer.
The code to handle malloc failure is quite tricky: we have to loop back over every previously added row and free it, then free(m->data), then free(m), then return NULL. You have to free everything in reverse order, because if you free m first then you don't have access to all of ms data (and you have to free all of that or else you leak memory).
for(size_t j = 0; j < width; j++) m->data[i][j] = fill;
This loops through all the elements of the row and fills them with the fill value. Not too bad compared to the above.
}
return m;
}
Once all that is done, we just return the m object. Users can now access m->data[1][2] and get the item in column 2, row 3. But before we're finished, since it took so much effort to create, this object will take a little effort to clean up when we're done. Let's make a cleanup function:
void free_Matrix(struct Matrix *m)
{
for(size_t i = 0; i < height; i++) free(m->data[i]);
free(m->data);
free(m);
}
This is doing (basically) what we had to do in case of allocation failure in the (let's go ahead and call it a) constructor, so if you get all that this should be cake.
It should be noted that this is not necessarily the best way to implement a matrix. If you require users to call a get(matrix, i, j) function for array access instead of directly indexing the data via matrix->data[i][j], you can condense the (complex) double ** allocation into a flat array, and manually perform the indexing via multiplication in your access functions. If you have C99 (or are willing to jump through some hoops for C89 support) you can even make the flat matrix data a part of your struct Matrix object allocation with a flexible array member, thus allowing you to deallocate your object with a single call to free. But if you understand how the above works, you should be well on your way to implementing either of those solutions.
As noted by #Chris Lutz, it's easier to start from scratch. As you can see from the other answers, you should normally use an integer type (e.g. size_t) to specify array lengths, and you should allocate not only the pointers, but also the structures where they are stored. And one more thing: you should always check the result of allocation (if malloc returned NULL). Always.
An idea: store 2D array in a 1D array
What I'd like to add: often it is much better to store entire matrix as a contiguous block of elements, and do just one array allocation. So the matrix structure becomes something like this:
#include <stdlib.h>
#include <stdio.h>
/* allocate a single contiguous block of elements */
typedef struct c_matrix_t {
size_t w;
size_t h;
double *elems; /* contiguos block, row-major order */
} c_matrix;
The benefits are:
you have to allocate memory only once (generally, a slow and unpredictable operation)
it's easier to handle allocation errors (you do not need to free all previously allocated rows if the last row is not allocated, you have only one pointer to check)
you get a contuguous memory block, which may help writing some matrix algorithms effectively
Probably, it is also faster (but this should be tested first).
The drawbacks:
you cannot use m[i][j] notation, and have to use special access functions (see get and set below).
Get/set elements
Here they are, the function to manipulate such a matrix:
/* get an element pointer by row and column numbers */
double* getp(c_matrix *m, size_t const row, size_t const col) {
return (m->elems + m->w*row + col);
}
/* access elements by row and column numbers */
double get(c_matrix *m, size_t const row, size_t const col) {
return *getp(m, row, col);
}
/* set elements by row and column numbers */
void set(c_matrix *m, size_t const row, size_t const col, double const val) {
*getp(m, row, col) = val;
}
Memory allocation
Now see how you can allocate it, please note how much simpler this allocation method is:
/* allocate a matrix filled with zeros */
c_matrix *alloc_c_matrix(size_t const w, size_t const h) {
double *pelems = NULL;
c_matrix *pm = malloc(sizeof(c_matrix));
if (pm) {
pm->w = w;
pm->h = h;
pelems = calloc(w*h, sizeof(double));
if (!pelems) {
free(pm); pm = NULL;
return NULL;
}
pm->elems = pelems;
return pm;
}
return NULL;
}
We allocate a matrix structure first (pm), and if this allocation is successful, we allocate an array of elements (pelem). As the last allocation may also fail, we have to rollback all the allocation we already made to this point. Fortunately, with this approach there is only one of them (pm).
Finally, we have to write a function to free the matrix.
/* free matrix memory */
void free_c_matrix(c_matrix *m) {
if (m) {
free(m->elems) ; m->elems = NULL;
free(m); m = NULL;
}
}
As the original free (3) doesn't take any action when it receives a NULL pointer, so neither our free_c_matrix.
Test
Now we can test the matrix:
int main(int argc, char *argv[]) {
c_matrix *m;
int i, j;
m = alloc_c_matrix(10,10);
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
set(m, i, j, i*10+j);
}
}
for (i = 0; i < 10; i++) {
for (j = 0; j < 10; j++) {
printf("%4.1f\t", get(m, i, j));
}
printf("\n");
}
free_c_matrix(m);
return 0;
}
It works. We can even run it through Valgrind memory checker and see, that it seems to be OK. No memory leaks.
I'm still new to C, malloc, and all that jazz, so I decided to write this to learn some more skills. The idea is, I'm reading in a bunch of ints from a file and putting them into a matrix (2d array). The start of the file says how many rows and columns there are, so it reads those numbers in and uses malloc to set up the 2d array.
int read_matrix(FILE *mat, int ***Z, int *x, int *y)
{
int i = 0;
int x_temp = 0;
int y_temp = 0;
if (fscanf(mat, "%d %d", &(*x), &(*y)) == EOF){
printf("File is not big enough to contain a matrix\n");
return -1;
}
printf("About to malloc %d\n", *x);
*Z = (int**) malloc(*x * sizeof(int*));
while (i < *x) {
printf("mallocing %d\n", i);
*Z[i] = (int*) malloc(*y * sizeof(int));
printf("malloced\n");
++i;
}
printf("Malloc complete\n");
/*Other unimportant code*/
}
The output reads:
About to malloc 3
mallocing 0
malloced
mallocing 1
Segmentation fault
So it's not mallocing anything but one int** in Z.. I think?
I'm very new to C, so I'm not sure if I've made some little mistake, or if I'm really going about this whole thing incorrectly. Any thoughts? Thanks!
The [] operator binds more closely than the unary * operator. Try changing *Z[i] to (*Z)[i] and see if your code behaves.
As a side note, it's also quite common in C to malloc a single array of (sizex*sizey) size, for a matrix and then index it as arr[x*sizey + y] or arr[y*sizex + x]. That more closely mimics what the language does with static arrays (e.g. if you declare int foo[10][10], all 100 ints are contiguous in memory and nowhere is a list of 10 int*'s stored.
I agree with both Walter and AndreyT. This is just some additional information.
Note that you can get away with just two malloc() calls, rather than *x + 1 - one big block for the ints themselves, and one for the row index.
*Z = malloc(*x * sizeof (*Z)[0]);
(*Z)[0] = malloc(*x * *y * sizeof (*Z)[0][0]);
for (i = 1; i < *x; i++) {
(*Z)[i] = (*Z)[0] + i * *y;
}
As Walter correctly noted in his answer, it should be (*Z)[i] = ..., not *Z[i] = ....
On top of that I'd suggest getting rid of that dereference/typecast hell present in your source code. Don't cast the result of malloc. Don't use type names under sizeof. Expressing it as follows
*Z = malloc(*x * sizeof **Z);
...
(*Z)[i] = malloc(*y * sizeof *(*Z)[i]);
wil make your code type-independent and much more readable.
A separate question is what on Earth made you use &(*x) in fscanf. Is this some kind of bizarre coding standard?