Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > malloc

Reply
Thread Tools

malloc

 
 
Joseph
Guest
Posts: n/a
 
      10-06-2003
I am trying to create a function that allocates memory for the matrix
through a function; like the code below. However, this does not seem to
work since I believe that the scope of the memory allocation only lasts
within the create function. Is there anyway around this? Thanx in
advance. I also DON'T want to declare int **matrix globally.


int main(void)
{
int **matrix;
create(matrix);
}

void create(int **matrix)
{ /*allocating mem for 2 by 3 int matrix*/
matrix = (int **)malloc(2*sizeof(int *));
matrix[0] = (int *)malloc(3*sizeof(int));
matrix[1] = (int *)malloc(3*sizeof(int));
}

 
Reply With Quote
 
 
 
 
Charles Harrison Caudill
Guest
Posts: n/a
 
      10-06-2003
Joseph <(E-Mail Removed)> wrote:
> I am trying to create a function that allocates memory for the matrix
> through a function; like the code below. However, this does not seem to
> work since I believe that the scope of the memory allocation only lasts
> within the create function. Is there anyway around this? Thanx in
> advance. I also DON'T want to declare int **matrix globally.



> int main(void)
> {
> int **matrix;
> create(matrix);
> }


> void create(int **matrix)
> { /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));
> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
> }


malloc allocates space on the heap. variable declarations in the
function allocate space on the stack. The stack goes away after
the function, the heap stays. That was too easy, and I'm bored,
so I'm going to rant...

Ok... time to have some fun...

(int *)malloc is redundant. The point of void * is that it matches
anything.

You could also statically allocate space on the stack inside your
main since the program dies when main does.

1) function pointers

int **create(int x, int y, void *(*malloc)(size_t)){
int i;
int **retval = (malloc)(sizeof(int) * x);
for(i = 0; i < y; i++)
retval[i] = (malloc)(sizeof(int) * y);
return retval;
}

2) triple pointers

int main( void ){
int **matrix;
create(42, 42, &matrix);
}

void create(int x, int y, int ***target){
int i;
*target = malloc(sizeof(int) * x);
for(i = 0; i < y; i++)
(*target)[i] = (malloc)(sizeof(int) * y);
}

ok, time to get back to compilers...

--
Harrison Caudill | .^ www.hypersphere.org
Computer Science & Physics Double Major | | Me*Me=1
Georgia Institute of Technology | '/ I'm just a normal guy
 
Reply With Quote
 
 
 
 
Pushkar Pradhan
Guest
Posts: n/a
 
      10-06-2003
I'm working on something similar, try the below,
they are 1-D matrices e.g. a 4X4 matrix will be accessed like this:
a[0], a[1], ... a[15].
If you want I have other functions like print_matrix also.
/*
** Generate a random matrix
*/
double * gen_matrix(int numRows, int numCols, int initialize)
{

double *x = NULL;
long i;

x = (double*)calloc( (numRows*numCols), sizeof(double) );
if(x == NULL) {
exit(-1);
}

/* initialize to zero */
if(!initialize) {
for(i = 0; i < numRows*numCols; i++) {
x[i] = 0.0;
/*printf("%d %g\n", i, x[i]);*/
}
}
else {
/* seed rand() with time so it starts randomly */
srand( (unsigned)time(NULL) );

for(i = 0; i < numRows*numCols; i++) {
x[i] = i;
/*printf("%d %g\n", i, x[i]);*/
}
}

return x;

}

int main(int argc, char **argv)
{

double *a = NULL;
double *b = NULL;
double *c = NULL;
/* other code */
a = gen_matrix(numRowsA, numColsA, 1);
b = gen_matrix(numRowsB, numColsB, 1);
c = gen_matrix(numRowsA, numColsB, 0);
....
free(a);
free(b);
free(c);

}





Joseph wrote:
> I am trying to create a function that allocates memory for the matrix
> through a function; like the code below. However, this does not seem to
> work since I believe that the scope of the memory allocation only lasts
> within the create function. Is there anyway around this? Thanx in
> advance. I also DON'T want to declare int **matrix globally.
>
>
> int main(void)
> {
> int **matrix;
> create(matrix);
> }
>
> void create(int **matrix)
> { /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));
> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
> }
>


 
Reply With Quote
 
Robert Stankowic
Guest
Posts: n/a
 
      10-06-2003

"Joseph" <(E-Mail Removed)> schrieb im Newsbeitrag
news:VU7gb.118421$(E-Mail Removed) ble.rogers.com...
> I am trying to create a function that allocates memory for the matrix
> through a function; like the code below. However, this does not seem to
> work since I believe that the scope of the memory allocation only lasts
> within the create function. Is there anyway around this? Thanx in
> advance. I also DON'T want to declare int **matrix globally.
>
>
> int main(void)
> {
> int **matrix;
> create(matrix);
> }
>
> void create(int **matrix)
> { /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));
> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
> }


For sure not the best solution, but the experts here will point out what's
flawed

#include <stdlib.h>
#include <stdio.h>

#define NUM_ROWS 2
#define NUM_COLS 3

int **destroy(int **matrix, int rows)
{
int i;
for(i = 0; i < rows; i++)
{
free(matrix[i]);
}
free(matrix);
matrix = NULL;
return matrix;
}

int ** create(int rows, int cols)
{
int **matrix;
int i;
int alloc_success = 1;

matrix = malloc(rows * sizeof *matrix);
if(matrix)
{
for(i = 0; i < rows; i++)
{
matrix[i] = malloc(cols * sizeof **matrix);
if(!matrix[i])
{
alloc_success = 0;
}
}
if(!alloc_success)
{
matrix = destroy(matrix, rows);
}
}

return matrix;
}



int main(void)
{
int i;
int j;
int **matrix = create(NUM_ROWS, NUM_COLS);

/*use matrix*/
if(matrix)
{
for(i = 0; i < NUM_ROWS; i++)
{
for(j = 0; j < NUM_COLS; j++)
{
matrix[i][j] = i * NUM_COLS + j;
printf("%d\n", matrix[i][j]);
}
}
/*cleanup*/
destroy(matrix, NUM_ROWS);
return EXIT_SUCCESS;
}
return EXIT_FAILURE;
}

Robert


 
Reply With Quote
 
Martijn
Guest
Posts: n/a
 
      10-06-2003
Pushkar Pradhan wrote:
> I'm working on something similar, try the below,
> they are 1-D matrices e.g. a 4X4 matrix will be accessed like this:
> a[0], a[1], ... a[15].
> If you want I have other functions like print_matrix also.
> /*
> ** Generate a random matrix
> */
> double * gen_matrix(int numRows, int numCols, int initialize)
> {
>
> double *x = NULL;
> long i;
>
> x = (double*)calloc( (numRows*numCols), sizeof(double) );
> if(x == NULL) {
> exit(-1);
> }
>


why do you use calloc if you initialize it right after, anyway?

> /* initialize to zero */
> if(!initialize) {
> for(i = 0; i < numRows*numCols; i++) {
> x[i] = 0.0;
> /*printf("%d %g\n", i, x[i]);*/
> }
> }
> else {
> /* seed rand() with time so it starts randomly */
> srand( (unsigned)time(NULL) );
>
> for(i = 0; i < numRows*numCols; i++) {
> x[i] = i;
> /*printf("%d %g\n", i, x[i]);*/
> }
> }
>
> return x;
>
> }


You could also have some fun and make a matrix type:

struct matrix
{
double* content;
unsigned int cols;
}

gen_matrix would be (I made it a litte more flexible, so it wouldn't exit on
failure):

struct matrix* gen_matrix(unsigned int rows, unsigned int cols)
{
struct matrix *matrix_ptr;

matrix_ptr = malloc(sizeof *matrix_ptr);
if ( matrix_ptr == NULL )
return ( NULL );

matrix_ptr->content = malloc(sizeof *matrix_ptr->content * rows *
cols);
if ( matrix_ptr->content == NULL )
{
free(matrix_ptr);
return ( NULL );
}

/* do any initialization of the content */

matrix_ptr->cols = cols;

return ( matrix_ptr );
}

Of course you could include the type it creates in both the name of the
structure and function (double vs int).

Now it is easier to use the indexes with getters and setters (uses 1-base
indexing, btw):

double get_matrix_value(struct matrix *matrix_ptr, unsigned int row,
unsigned int col)
{
if ( row == 0 || col == 0 )
return ( 0.0 ); /* set an error here */

return ( matrix_ptr->content[matrix_ptr->cols * (row - 1) + (col -
1)] );
}

Of course I don't check on out of bounds, so you would have to tweak this to
your needs (e.g. add the rows property to the structure as well, and check
for overflow).

Hope this helps,

--
Martijn
http://www.sereneconcepts.nl


 
Reply With Quote
 
Mike Wahler
Guest
Posts: n/a
 
      10-06-2003
"Joseph" <(E-Mail Removed)> wrote in message
news:VU7gb.118421$(E-Mail Removed) ble.rogers.com...
> I am trying to create a function that allocates memory for the matrix
> through a function; like the code below. However, this does not seem to >

work since I believe that the scope of the memory allocation only lasts >
within the create function. Is there anyway around this? Thanx in
> advance. I also DON'T want to declare int **matrix globally.
>
>
> int main(void)
> {
> int **matrix;
> create(matrix);
> }
>
> void create(int **matrix)
> { /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));
> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
> }


It's always a good idea to search past messages,
very likely your question has already been asked
and answered. From one of my recent posts (Sep 26):


#include <stdio.h>
#include <stdlib.h>

double **alloc2d(size_t rows, size_t cols)
{
double **result;
size_t row = 0;
size_t col = 0;

if(result = malloc(rows * sizeof *result))
{
if(*result = malloc(rows * cols * sizeof **result))
for(row = 1; row < rows; ++row)
result[row] = *result + row * cols;
else
{
free(result);
result = NULL;
}
}

return result;
}

void release2d(double **arr)
{
free(*arr);
free(arr);
}

void populate2d(double **arr, size_t rows, size_t cols)
{
size_t row = 0;
size_t col = 0;

for(row = 0; row < rows; ++row)
for(col = 0; col < cols; ++col)
arr[row][col] = row * cols + col;
}

void show2d(double **arr, size_t rows, size_t cols)
{
size_t row = 0;
size_t col = 0;

for(row = 0; row < rows; ++row)
{
for(col = 0; col < cols; ++col)
printf("%4.0f", arr[row][col]);

putchar('\n');
}
}

int main()
{
size_t rows = 10;
size_t cols = 10;
size_t row = 0;
size_t col = 0;
double **arr = NULL;
const int retcodes[] = {EXIT_FAILURE, EXIT_SUCCESS};
int status = 0;

if(status = (arr = alloc2d(rows, cols)) != NULL)
{
populate2d(arr, rows, cols);
show2d(arr, rows, cols);
release2d(arr);
}

printf("%s\n", status ? "" : "Cannot allocate memory");
return retcodes[status];
}

HTH,
-Mike



 
Reply With Quote
 
Joseph
Guest
Posts: n/a
 
      10-06-2003
I fail to understand why that the memory allocated in the void
create(int **matrix) does not remain. I passed the address of matrix so
shouldn't it still have the allocated memory when it returns to main.
The problem i am having is understanding why the printf statement in the
code below gives the value. I would have expected it to be 123 which is
the value I set it to in the create. Thanx in advance.

void create(int **matrix);

int main(void)
{
int **matrix;
create(matrix);

printf("%d", matrix[1][1]); /* ? */
}

void create(int **matrix)
{ /*allocating mem for 2 by 3 int matrix*/
matrix = (int **)malloc(2*sizeof(int *));
matrix[0] = (int *)malloc(3*sizeof(int));
matrix[1] = (int *)malloc(3*sizeof(int));

matrix[1][1] = 123;
}

 
Reply With Quote
 
Barry Schwarz
Guest
Posts: n/a
 
      10-06-2003
On Mon, 06 Oct 2003 06:24:53 GMT, Joseph <(E-Mail Removed)> wrote:

>I am trying to create a function that allocates memory for the matrix
>through a function; like the code below. However, this does not seem to
>work since I believe that the scope of the memory allocation only lasts
>within the create function. Is there anyway around this? Thanx in
>advance. I also DON'T want to declare int **matrix globally.
>
>
>int main(void)
>{
> int **matrix;
> create(matrix);


Problems here:

matrix is uninitialized. Passing an uninitialized value to a
function (or any attempt to evaluate an uninitialized value) invokes
undefined behavior.

There is no way for the function to return the value/address of
the matrix it creates. Remember that c passes by value so that
whatever the function does to matrix actually happens to a copy of
matrix that is lost when the function returns.

There is no prototype in scope for create.

>}


The solution to the prototype problem is obvious

There are two popular solutions to the other problems:

Since you only want to return one value, define the function to
do just that, as with the prototype
int** create(void);
Your function call the function with something like
matrix = create();
and the function would then look like
int** create(void){
int **ptr, i;
ptr = malloc(N * sizeof *ptr);
if (ptr == NULL){/* error handling */}
for (i = 0; i < M; i++){
ptr[i] = malloc(N * sizeof *ptr[i]);
if (ptr[i] == NULL){/* error handling */}
}
return ptr;
}

If you really want the value returned in a variable, pass the
address of that variable to the function which can then dereference
the address and update the variable directly. The prototype would
look like
void create(int***);
The call would look like
create(&matrix);
and the function would look like
void create (int ***ptr){
int i;
*ptr = malloc(N * sizeof **ptr);
if ...
for (i = 0; i < M; i++){
(*ptr)[i] = malloc(M * sizeof *(*ptr)[i]);
if ...
}
}

>
>void create(int **matrix)
>{ /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));


While you are at it, NEVER cast the return from malloc. It can never
help but it can suppress compiler diagnostics you want to see.

> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
>}




<<Remove the del for email>>
 
Reply With Quote
 
Robert Stankowic
Guest
Posts: n/a
 
      10-06-2003

"Joseph" <(E-Mail Removed)> schrieb im Newsbeitrag
news:RHfgb.123896$(E-Mail Removed) ble.rogers.com...
> I fail to understand why that the memory allocated in the void
> create(int **matrix) does not remain. I passed the address of matrix so
> shouldn't it still have the allocated memory when it returns to main.
> The problem i am having is understanding why the printf statement in the
> code below gives the value. I would have expected it to be 123 which is
> the value I set it to in the create. Thanx in advance.
>
> void create(int **matrix);
>
> int main(void)
> {
> int **matrix;
> create(matrix);


Here you pass a _copy_ of matrix. In create() you request (and hopefully
get, because you don't check the return value of malloc() for NULL) some
memory and assign the pointer malloc() returns to the _copy_ of matrix. This
_does not_ change the value of the original matrix in main(). So as soon as
you return from create() the requested memory is still there, but you lost
the pointer to it and therefore you have absolutely no way to access it.
there are two ways out:
1) look at my example I posted elsethread
2) pass a _pointer_ to matrix to create() like in

create(&matrix);

Now create gets the _address_ of the pointer and thus can modify the
**matrix in main()
(see below)

>
> printf("%d", matrix[1][1]); /* ? */
> }
>
> void create(int **matrix)


This must be
void create(int ***ptr_to_matrix)

> { /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));


*ptr_to_matrix = (int **)malloc(2*sizeof(int *));
or better
#include <stdlib.h> before your actual code and get rid of the cast and use
the preferred way of using the sizeof, which makes the statement remain
correct even if you change the type of **matrix:

*ptr_to_matrix = malloc(2 * sizeof **ptr_to_matrix);
......

(*ptr_to_matrix)[0] = malloc(3 * sizeof ***ptr_to_matrix);

> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
>
> matrix[1][1] = 123;
> }


I personally _hate_ more than two levels of indirection, so I prefer to
return a pointer to the allocated memory and assign the returned pointr to
the original in the calling functions (see my example elsethread).

Please look at the examples given in our answers for better solutions and
proper error checking
HTH
Robert


 
Reply With Quote
 
Al Bowers
Guest
Posts: n/a
 
      10-06-2003


Joseph wrote:
> I am trying to create a function that allocates memory for the matrix
> through a function; like the code below. However, this does not seem to
> work since I believe that the scope of the memory allocation only lasts
> within the create function. Is there anyway around this? Thanx in
> advance. I also DON'T want to declare int **matrix globally.
>
>
> int main(void)
> {
> int **matrix;
> create(matrix);
> }
>
> void create(int **matrix)
> { /*allocating mem for 2 by 3 int matrix*/
> matrix = (int **)malloc(2*sizeof(int *));
> matrix[0] = (int *)malloc(3*sizeof(int));
> matrix[1] = (int *)malloc(3*sizeof(int));
> }
>


The parameter matrix in function create is passed by value. A copy
is made and used in the function. It is changed with the malloc call.
But since it is a copy, matrix in function main remains unchanged.
To correct this and also add some safety and functionality make the
prototype:

int create(int ***matrix):

the definition and test code:

#include <stdlib.h>
#include <stdio.h>

int create(int ***matrix)
{
*matrix = malloc(2*(sizeof **matrix));
if(*matrix == NULL) return 0;
if(((*matrix)[0] = malloc(3*(sizeof ***matrix))) == NULL)
{
free(*matrix);
return 0;
}
if(((*matrix)[1] = malloc(3*(sizeof ***matrix))) == NULL)
{
free((*matrix)[0]);
free(*matrix);
return 0;
}
/* test */
(*matrix)[1][1] = 122;
return 1;
}

int main(void)
{
int **matrix;
if(create(&matrix))
printf("matrix[1][1] = %d\n",matrix[1][1]);
/* TODO Write code on free the dymanic allocations */
return 0;
}

--
Al Bowers
Tampa, Fl USA
mailto: http://www.velocityreviews.com/forums/(E-Mail Removed) (remove the x)
http://www.geocities.com/abowers822/

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
to malloc or not to malloc?? Johs32 C Programming 4 03-30-2006 10:03 AM
porting non-malloc code to malloc micromysore@gmail.com C Programming 3 02-19-2005 05:39 AM
Malloc/Free - freeing memory allocated by malloc Peter C Programming 34 10-22-2004 10:23 AM
free'ing malloc'd structure with malloc'd members John C Programming 13 08-02-2004 11:45 AM
Re: free'ing malloc'd structure with malloc'd members ravi C Programming 0 07-30-2004 12:42 PM



Advertisments