I have the following function:
int* create_matrix_2(int rows, int cols)
{
double (*A)[rows][cols] = malloc(sizeof(int[rows][cols]));
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
*A[row][col] = row * cols + col;
}
}
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
printf("%lf, " , *A[row][col]);
}
printf("\n");
}
return A;
}
My question is: How do I return the VLA from that function, what is the type and how do I write that as a function signature and how do I use it where I receive the returned array?
At the moment I am trying to do it like this:
int (*matrix2)[height][width] = create_matrix_2(height, width);
for (int row = 0; row < height; row++)
{
for (int col = 0; col < width; col++)
{
printf("%d" , (*matrix2)[row][col]);
}
printf("\n");
}
and then run: gcc 2d_array_test.c -o 2d_array_test.out -std=c99 -O0
But this results in the following problems:
2d_array_test.c: In function ‘main’:
2d_array_test.c:35:34: warning: initialization from incompatible pointer type [enabled by default]
int (*matrix2)[height][width] = create_matrix_2(height, width);
^
2d_array_test.c: In function ‘create_matrix_2’:
2d_array_test.c:105:2: warning: return from incompatible pointer type [enabled by default]
return A;
^
EDIT#1:
I tried to use the code suggested by alk, but it gives me a lot of errors while compiling. Here is a separate programm, which contains your suggested code with a main function: http://pastebin.com/R6hKgvM0
I get the following errors:
2d_array_test_new.c: In function ‘main’:
2d_array_test_new.c:18:2: warning: passing argument 3 of ‘create_matrix’ from incompatible pointer type [enabled by default]
if (-1 == create_matrix(height, width, &matrix))
^
2d_array_test_new.c:10:5: note: expected ‘int **’ but argument is of type ‘int (**)[(sizetype)(height)][(sizetype)(width)]’
int create_matrix(size_t, size_t, int**);
^
2d_array_test_new.c: At top level:
2d_array_test_new.c:37:5: error: conflicting types for ‘create_matrix’
int create_matrix(size_t rows, size_t cols, int(**a)[rows][cols])
^
2d_array_test_new.c:10:5: note: previous declaration of ‘create_matrix’ was here
int create_matrix(size_t, size_t, int**);
^
2d_array_test_new.c: In function ‘create_matrix’:
2d_array_test_new.c:45:11: error: ‘EINVAL’ undeclared (first use in this function)
errno = EINVAL;
^
2d_array_test_new.c:45:11: note: each undeclared identifier is reported only once for each function it appears in
2d_array_test_new.c:40:6: warning: variable ‘errno’ set but not used [-Wunused-but-set-variable]
int errno;
^
The errors mainly seem to be about the return type. How do I write the type of that array correctly?
refering the 1st warning:
warning: initialization from incompatible pointer type
Here
int (*matrix2)[height][width] = create_matrix_2(height, width);
int (*matrix2)[height][width] and int * simply aren't the same.
refering the 2nd warning:
warning: return from incompatible pointer type
This dues to defining
double (*A)[rows][cols] = malloc(sizeof(int[rows][cols]));
while returning A from int * create_matrix_2().
int * and double (*A)[rows][cols] also aren't the same.
I propose you change the function like this:
#include <errno.h> /* for errno and EINVAL */
#include <stdlib.h> /* for malloc() */
int create_matrix_2(size_t rows, size_t cols, int(**a)[rows][cols])
{
int result = 0;
if (NULL == a)
{
result = -1;
errno = EINVAL;
}
else
{
(*a) = malloc(sizeof **a);
if (NULL == (*a))
{
result = -1;
}
else
{
for (size_t row = 0; row < rows; row++)
{
for (size_t col = 0; col < cols; col++)
{
(**a)[row][col] = row * cols + col;
}
}
for (size_t row = 0; row < rows; row++)
{
for (size_t col = 0; col < cols; col++)
{
printf("%d, " , (**a)[row][col]);
}
printf("\n");
}
}
}
return result;
}
and call it like this:
#include <stdlib.h>
#include <stdio.h>
int create_matrix_2(size_t rows, size_t cols, int(**a)[rows][cols]);
int main(void)
{
int result = EXIT_SUCCESS;
int (*matrix2)[height][width] = NULL;
if (-1 == create_matrix_2(height, width, &matrix2))
{
perror("create_matrix_2() failed");
result = EXIT_FAILURE;
}
else
{
for (size_t row = 0; row < height; row++)
{
for (size_t col = 0; col < width; col++)
{
printf("%d, " , (*matrix2)[row][col]);
}
printf("\n");
}
free(matrix2);
}
return result;
}
First, there are some issues with your code. You have a double array pointer pointing to a 2D array of ints, that doesn't make any sense.
Also, since A is a pointer to a 2D array, you can't do *A[row][col]. Because [] has higher precedence than *, so the code is equivalent to *(A[row][col]). Which is turn means "give me row number of 2D matrices, then...". The code will end up far out of bounds.
The trick when declaring an array pointer to a dynamically allocated multi-dimensional array is to omit the inner-most dimension. That way you can use syntax just like you would with a regular multi-dimensional array.
double (*A)[cols] = malloc(sizeof(double[rows][cols]));
...
A[x][y] = ...;
A[x][y] will then mean "In my array A, where each item is an array of size cols, access array number x and then index y in that array".
As for the question of how to return an array of this type... well you can't, because the function declaration would have to contain the dimensions of the array pointer. It would have to be a monstrosity like this:
double (*create_matrix_2(int rows, int cols))[rows][cols] // wont compile
If we ignore that the C syntax for returning array pointers (and function pointers) is completely FUBAR, the above isn't valid C. Because rows and cols would then have to be known at compile time.
The solution to clearing up the above mess and fixing the issue at the same time is to return the array pointer through a parameter:
void create_matrix_2 (int rows, int cols, double(**array)[rows][cols])
{
// omit inner-most dimension to get sane syntax:
double (*A)[cols] = malloc(sizeof(double[rows][cols]));
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
A[row][col] = row * cols + col;
}
}
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
printf("%lf, " , A[row][col]);
}
printf("\n");
}
// "brute" pointer conversion but doesn't break aliasing:
*array = (void*)A;
}
The short answer is that you can't.
The problem is that the type returned from a function must be fixed at compile time and cannot depend on the numeric value (supplied at run time) of its parameters.
What you can do, however, is change your create_matrix2() to return a void pointer. This uses the fact that, in C, (almost) any pointer can be implicitly converted to a void pointer, and vice versa.
void *create_matrix2(int rows, int columns)
{
/* as you've implemented it, except that A should be int not double */
}
int main()
{
int rows = 2, cols = 3;
int (*m)[rows][cols] = create_matrix2(rows, cols);
/* use *m as a pointer to an array with 2 rows and 3 cols */
}
It then delivers the illusion of what you seek.
The danger of this - and the reason I use the word "illusion" just now - is that the conversion to and from a void pointer prevents the compiler doing type checking. So this will sail past the compiler, but cause undefined behaviour due to falling off the end of arrays.
int main()
{
int rows = 2, cols = 3;
int (*m)[rows][cols] = create_matrix2(rows-1, cols-1); /* whoops - deliberate typos here */
/* use *m as a pointer to an array with 2 rows and 3 cols */
}
because this effectively tells the compiler to treat the dynamically allocated array as if it has more rows and columns than actually allocated in the function.
sample
#include <stdio.h>
#include <stdlib.h>
void * create_matrix_2(int rows, int cols){
int (*A)[rows][cols] = malloc(sizeof(int[rows][cols]));
for (int row = 0; row < rows; row++){
for (int col = 0; col < cols; col++){
(*A)[row][col] = row * cols + col;
}
}
for (int row = 0; row < rows; row++){
for (int col = 0; col < cols; col++){
printf("%d, " , (*A)[row][col]);
}
printf("\n");
}
return A;
}
int main(void){
int width = 5, height = 3;
int (*matrix2)[height][width] = create_matrix_2(height, width);
for (int row = 0; row < height; row++){
for (int col = 0; col < width; col++){
printf("%d " , (*matrix2)[row][col]);
}
printf("\n");
}
free(matrix2);
return 0;
}
Related
I have a task of creating a matrix, that is the size of NxN, where N is a given parameter.
The matrix should be filled with random 0s and 1s.
I have tried the following code:
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/time.h>
#include <time.h>
#include <sys/wait.h>
#include <pthread.h>
int** createMatr(int N){
int** matr[10][10];
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
int rnd = rand() % 2;
matr[i][j] = rnd;
}
}
return matr;
}
void setValMatr(int N, int** matr[][10], int** newMatr[][10]){
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
newMatr[i][j] = matr[i][j];
}
}
}
void printMatr(int N, int** matr[][10]){
for(int i = 0; i < N; i++){
for(int j = 0; j < N; j++){
printf("%d ",matr[i][j]);
}
printf("\n");
}
}
int main(int argc, char* argv[]){
if(argc!=2){
perror("parameter error\n");
}
int N = atoi(argv[1]);
int** matrix[10][10];
int** helper[10][10];
setValMatr(N,createMatr(N), matrix);
setValMatr(N,matrix,helper);
printMatr(N, matrix);
return 0;
}
The compilation warnings this gives me are:
┌──(kali㉿kali)-[~/Desktop/Cprog/Linux2_Lab2]
└─$ gcc gvim2135_L2_1.c -o p
gvim2135_L2_1.c: In function ‘createMatr’:
gvim2135_L2_1.c:15:24: warning: assignment to ‘int **’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
15 | matr[i][j] = rnd;
| ^
gvim2135_L2_1.c:18:12: warning: returning ‘int ** (*)[10]’ from a function with incompatible return type ‘int **’ [-Wincompatible-pointer-types]
18 | return matr;
| ^~~~
gvim2135_L2_1.c:18:12: warning: function returns address of local variable [-Wreturn-local-addr]
gvim2135_L2_1.c: In function ‘main’:
gvim2135_L2_1.c:47:18: warning: passing argument 2 of ‘setValMatr’ from incompatible pointer type [-Wincompatible-pointer-types]
47 | setValMatr(N,createMatr(N), matrix);
| ^~~~~~~~~~~~~
| |
| int **
gvim2135_L2_1.c:21:30: note: expected ‘int ** (*)[10]’ but argument is of type ‘int **’
21 | void setValMatr(int N, int** matr[][10], int** newMatr[][10]){
| ~~~~~~^~~~~~~~~~
After running I get the error:
Segmentation fault
With the int** matrix[][] notation you are not create a matrix but a matrix of matrix pointer. You can see a matrix as a pointer to an array of array: int** matrix.
So, your code become:
int** create_matrix(int size) {
int i, j, **matrix = (int **)malloc(size * sizeof(int*));
for (i = 0; i < size; ++i) {
matrix[i] = (int *)malloc(size * sizeof(int));
for (j = 0; j < size; ++j) {
matrix[i][j] = rand() % 2;
}
}
return matrix;
}
void print_matrix(int** matrix, int size) {
int i, j;
for (i = 0; i < size; ++i) {
for (j = 0; j < size; ++j) {
printf("%d | ", matrix[i][j]);
}
printf("\n");
}
}
Use a structure to describe matrices in general, for example
typedef struct imatrix imatrix;
struct imatrix {
int rows;
int cols;
int *data;
};
static inline int imatrix_get(const imatrix *im, int row, int col, int outside)
{
if (!im || row < 0 || col < 0 || row >= im->rows || col >= im->cols)
return outside;
else
return im->data[row * (size_t)(im->cols) + col];
}
static inline void imatrix_set(imatrix *im, int row, int col, int value)
{
if (im && row >= 0 && col >= 0 && row < im->rows && col < im->cols)
im->data[row * (size_t)(im->cols) + col] = value;
}
void imatrix_free(imatrix *im)
{
if (im) {
free(im->data);
im->rows = 0;
im->cols = 0;
im->data = NULL;
}
}
int imatrix_new(imatrix *im, int rows, int cols)
{
if (!im)
return -1; /* No matrix specified */
im->rows = 0;
im->cols = 0;
im->data = NULL;
if (rows < 1 || cols < 1)
return -2; /* Invalid size */
const size_t rowsize = (size_t)cols * sizeof im->data[0];
const size_t datasize = (size_t)rows * rowsize;
if ((size_t)(datasize / rows) != rowsize ||
(size_t)(rowsize / cols) != sizeof im->data[0])
return -3; /* Matrix is too large */
im->data = malloc(datasize);
if (!im->data)
return -4; /* Not enough memory available */
im->rows = rows;
im->cols = cols;
return 0;
}
The idea is that imatrix is a structure that contains the number of rows and columns in the matrix, and a pointer to the (array of) data elements. If m is a properly initialized imatrix, element at row r, column c is m->data[r*(size_t)(m->cols) + c].
Note that the int type is not large enough on many architectures to for the index, so we need to cast the number of columns to the proper type, size_t (which is the proper type for all in-memory sizes and offsets).
If you have e.g. imatrix m;, you need to initialize it (and dynamically allocate memory for it, say 30 rows and 20 columns) by calling imatrix_new(&m, 30, 20);. It will return 0 if successful, and negative error code if it fails.
The imatrix_get() and imatrix_set() functions are convenient accessor functions, that will not try to access the matrix contents outside of bounds. You do not need to use them in your own functions, if you make sure your loops etc. are always within range; you can then safely use the im->data[r * (size_t)(im->cols) + c] idiom.
When you no longer need the matrix, you discard it with a simple imatrix_free(&m) call.
I have created two matrices in C with the following code:
static allocation method
int data[NMAX][NMAX]; // define NMAX 10 is in header
dynamic allocation method
int** data = (int**) malloc(sizeof(int*) * N);
for (int i = 0; i < N; i++) {
data[i] = (int*) malloc(sizeof(int) * M);
}
now i want to insert data into them with ONE function like so:
int inputMatrix(int **data, int N, int M) { ... }
How can i make the same function declaration work for both array types?
Currently it outputs
expected 'int **' but argument is of type 'int ** (*)[10]'
I have tried creating the static array like this:
int* data[NMAX];
for (int i = 0; i < N; i++) {
data[i] = (int[NMAX]) {};
}
but this code produces a matrix with every line being the same after I input numbers into it
The function inputMatrix will take an array whose elements are pointers to int, so you can create an array that holds pointers to each rows of statically allocated array and pass that to the function.
Construction of the pointer array can be done like this:
int data[NMAX][NMAX];
int *pdata[NMAX]; // array of pointers
for (int i = 0; i < N; i++) {
pdata[i] = data[i]; // the array data[i] is converted to pointers to their first elements here
}
##EDI##
You array pointers
int arr[10][5];
int main(void)
{
srand(time(NULL));
fillArray(5, 10, arr);
printArray(5, 10, arr);
}
See the implementations below https://godbolt.org/z/M6GhrEojn
Do not use arrays of pointers. Use array pointers instead. You remove one level of indirection and you can allocate and free it using one function call. As the whole array is a contignous chunk of memory it is much easier for processor yo use the cache.
void *allocateArray(size_t rows, size_t cols)
{
int (*a)[cols] = malloc(rows * sizeof(*a));
return a;
}
and example usage:
void fillArray(size_t cols, size_t rows, int (*arr)[cols])
{
for(size_t row = 0; row < rows; row++)
for(size_t col = 0; col < cols; col++)
arr[row][col] = rand();
}
void printArray(size_t cols, size_t rows, int (*arr)[cols])
{
for(size_t row = 0; row < rows; row++)
{
for(size_t col = 0; col < cols; col++)
printf("[%02zu][%02zu]%d,\t", row, col, arr[row][col]);
printf("\n");
}
}
int main(void)
{
size_t cols, rows;
scanf("%zu,%zu", &rows, &cols);
printf("rows:%zu, cols:%zu", rows, cols);
int (*array)[cols] = allocateArray(rows, cols);
srand(time(NULL));
printf("%p\n", array);
if(array)
{
fillArray(rows, cols, array);
printArray(rows, cols, array);
}
free(array);
}
I have the following struct and function. After allocating a 2D array, I want to return it but for some reason I keep getting the error: "warning: returning ‘int **’ from a function with incompatible return type ‘Array *’ {aka ‘struct array *’} [-Wincompatible-pointer-types]"
typedef struct array
{
int n1;
int n2;
int *data;
} Array;
Array *array_create(int n1, int n2)
{
int **arr = malloc(n1 * sizeof(int*));
for (int i = 0; i < n1; i++)
{
arr[i] = malloc(n2*sizeof(int));
}
Array values = {n1, n2, *arr};
return values;
}
Here's some code from the main function for some clarity:
{
Array *arr = array_create(4, 4);
int cnt = 1;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
array_set(arr, i, j, cnt++);
}
}
I believe you want to return a pointer to your struct, so you have to malloc it first:
const Array *values = malloc(sizeof(*values));
return values
And if you want your Array to be const you need to change the function declaration:
const Array *array_create(int n1, int n2)
and the variable declaration in the main function:
const Array *arr = array_create(4, 4);
you do not allocate a 2D array only array of pointers.
Use the correct types of sizes (size_t)
Your pointer has the wrong type.
I would do it different away to avoid complicated malloc patterns.
typedef struct array
{
size_t rows;
size_t cols;
int data[];
} Array;
Array *array_alloc(size_t rows, size_t cols)
{
Array *array = malloc(sizeof(*array) + rows * cols * sizeof(array -> data[0]));
if(array)
{
array -> rows = rows;
array -> cols = cols;
}
return array;
}
#define ARR(var) ((int (*)[var -> cols])(var -> data))
int main(void)
{
Array *a = array_alloc(10,20);
for(size_t row = 0; row < 10; row++)
{
for(size_t col = 0; col < 20; col++)
{
ARR(a)[row][col] = row *1000 + col;
}
}
for(size_t row = 0; row < 10; row++)
{
for(size_t col = 0; col < 20; col++)
{
printf("[%5d] ", ARR(a)[row][col]);
}
printf("\n");
}
}
I'd like to make an array (called Csend) and then create a function which modifies it slightly, such as by adding 0.05 to every element. The problem I'm having is with the formatting of the array, I'm not sure how to pass it into a function properly. I've allocated the memory in this way following this guide so that I can later put it in MPI_Send and MPI_Recv.
Here is my attempt:
#include "stdio.h"
#include "stdlib.h"
#include "mpi.h"
#include "math.h"
int main(int argc, char **argv) {
int N = 32;
int dim = 3;
float a = 10.0; // size of 3D box
int size, rank, i, j, k, q;
float **C, **Csend, **Crecv;
float stepsize = 0.05;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
float **alloc_2d_float(int rows, int cols) {
float *data = (float *)malloc(N*dim*sizeof(float));
float **array= (float **)malloc(N*sizeof(float*));
for(i=0; i<N; i++) {
array[i] = &(data[dim*i]);
}
return array;
}
C = alloc_2d_float(N,dim);
Csend = alloc_2d_float(N,dim);
Crecv = alloc_2d_float(N,dim);
if(rank == 0) {
for (i = 0; i < N; i++) {
for (j = 0; j < dim; j++) {
Csend[i][j] = (float)rand()/(float)(RAND_MAX/a);
}}
}
// FUNCTION TO MODIFY MATRIX //
float randomsteps(float *matrix, int N, int dim) {
int i, j;
for(i = 0; i < N; i = i+2) {
for (j = 0; j < dim; j++) {
*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize;
}
}
return matrix;
}
C = randomsteps(Csend, 32, 3);
for (i=0; i<N; i++){
for (j=0; j<dim; j++){
printf("%f, %f\n", Csend[i][j], C[i][j]);
}
}
MPI_Finalize();
return 0;
}
The problem I'm having is that formatted like it is here, I get error messages, and formatted in ways that didn't give error messages, C was just empty.
Here is the error message:
test.c: In function ‘randomsteps’:
test.c:46: error: incompatible types when returning type ‘float *’ but ‘float’ was expected
test.c: In function ‘main’:
test.c:49: warning: passing argument 1 of ‘randomsteps’ from incompatible pointer type
test.c:39: note: expected ‘float *’ but argument is of type ‘float **’
test.c:49: error: incompatible types when assigning to type ‘float **’ from type ‘float’
Thanks for the help!
You are confusing between 1 dimensional representation of a matrix and a two dimensional pointer to pointer approach of it.
*((matrix+i*N) + j) = *((matrix+i*N) + j) + stepsize; -> This line implies that matrix is just linear collection and it is accessed like a matrix using index manipulation.
float **C; -> This implies you want a matrix which can be accessed as C[i][j].
Stick to any one of the representations. Also, since your function returns a matrix, the return type should be either float* (if the 2d matrix is considered linear with array manipulation) of float** if you want a 2d matrix without index manipulation access.
float* matrix = malloc(row * cols * sizeof(float)); // This is a linear version.
// matrix[i*cols + j] gives you the (i, j)th element.
float** matrix = malloc(rows * sizeof(float*));
for(int i = 0; i < rows; ++i)
matrix[i] = malloc(cols * sizeof(float));
// Now you can access matrix[i][j] as the (i, j)th element.
Here is a way to interconvert between the two formats.
float* linearize(float** matrix, unsigned int rows, unsigned int cols)
{
float* linear = malloc(rows * cols * sizeof(float));
if(linear)
{
for(unsigned int i = 0; i < rows; ++i)
for(unsigned int j = 0; j < cols; ++j)
linear[i*cols + j] = matrix[i][j] ;
}
return linear ;
}
float** unlinearize(float* linear, unsigned int rows, unsigned int cols)
{
float** matrix = malloc(rows * sizeof(float*));
if(matrix)
{
for(unsigned int i = 0; i < rows; ++i)
{
matrix[i] = malloc(cols * sizeof(float));
if(matrix[i])
{
for(unsigned int j = 0; j < cols; ++j)
matrix[i][j] = linear[i*cols + j] ;
}
}
}
return matrix ;
}
I would like a function to return an array, or a pointer to an array, in either c or c++, that does something like the following:
double[][] copy(double b[][], int mx, int my, int nx, int ny)
{
double[nx][ny] a;
int i,j;
for(i = mx; i<= nx; ++i)
for(j = my; j<= ny; ++j)
a[i][j] = b[i][j];
return a;
}
void main(void){
double A[2][3];
double B[2][3] = {{1,2}{3,4}{5,6}};
A = copy(B,0,0,1,2);
}
This is the proper method for returning an array from a function is as follows:
#define NUM_ROWS (5)
#define NUM_COLS (3)
char **createCharArray(void)
{
char **charArray = malloc(NUM_ROWS * sizeof(*charArray));
for(int row = 0; row < NUM_ROWS; row++)
charArray[row] = malloc(NUM_COLS * sizeof(**charArray));
return charArray;
}
In this example, the above function can be called like this:
char **newCharArray = createCharArray();
newCharArray can now be used:
char ch = 'a';
for(int row = 0; row < NUM_ROWS; row++)
for(int col = 0; col < NUM_COLS; col++)
newCharArray[row][col] = ch++;
An array can be passed as an argument to function similarly:
void freeCharArray(char **charArr)
{
for(int row = 0; row < NUM_ROWS; row++)
free(charArr[row]);
free(charArr);
}
You can return the double ** from your copy function like this.
double ** copy(double *src, int row, int col)
{
// first allocate the array with required size
double **copiedArr = (double **) malloc(sizeof(double *)*row);
for(int i=0;i<row;i++)
{
// create space for the inner array
*(copiedArr+i) = (double *) malloc(sizeof(double)*col);
for(int j=0; j<col; j++)
{
// copy the values from source to destination.
*(*(copiedArr+i)+j) = (*(src+i+j));
}
}
// return the newly allocated array.
return copiedArr;
}
call to this function is done like this.
double src[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
double **dest = copy(&src[0][0],3,3); //here is your new array
Here you have to assign returned value of copy() to double** not to double[][].
If you try to assign the returned value to array then it will generate "Incompatible types" error (detail).
As memory allocated to copiedArray on the heap so you have to take responsibility to clear the memory.
void freemem(double **mem, int row)
{
for(int i=0;i<row; i++)
{
free(*(mem+i));
}
free(mem);
}
I also want to point out some correction in your sample code:
return type of main should be int.
one should put the return statement at the end of main.
you can't return the stack allocated value, it is cause of crash
in most of cases.