473,326 Members | 2,732 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

malloc

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));
}

Nov 13 '05 #1
14 7815
Joseph <ke******@rogers.com> 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
Nov 13 '05 #2
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));
}


Nov 13 '05 #3
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
Nov 13 '05 #4

"Joseph" <ke******@rogers.com> schrieb im Newsbeitrag
news:VU********************@news02.bloor.is.net.ca 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
Nov 13 '05 #5
"Joseph" <ke******@rogers.com> wrote in message
news:VU********************@news02.bloor.is.net.ca 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

Nov 13 '05 #6
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;
}

Nov 13 '05 #7
On Mon, 06 Oct 2003 06:24:53 GMT, Joseph <ke******@rogers.com> 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>>
Nov 13 '05 #8

"Joseph" <ke******@rogers.com> schrieb im Newsbeitrag
news:RH********************@news02.bloor.is.net.ca 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
Nov 13 '05 #9


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: xa*@abowers.combase.com (remove the x)
http://www.geocities.com/abowers822/

Nov 13 '05 #10
try that (not tested):

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));
}

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 13 '05 #11

"cody" <do*********************@gmx.de> wrote in message
news:bm************@ID-176797.news.uni-berlin.de...
try that (not tested):

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

sounds better..
}

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));
}

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk

Nov 13 '05 #12
In <bm************@ID-176797.news.uni-berlin.de> "cody" <do*********************@gmx.de> writes:
try that (not tested):

int main(void)
{
int **matrix;
create(matrix);
Undefined behaviour: you're implicitly declaring create() as function
returning int. You're also passing create() an uninitialised pointer of
the wrong type.
}

void create(int ***matrix)
{ /*allocating mem for 2 by 3 int matrix*/
*matrix = (int **)malloc(2*sizeof(int *));
Undefined behaviour: you're implicitly declaring malloc as a function
returning int. Due to the bogus cast, the compiler is not even required
to diagnose the bug.
(*matrix)[0] = (int*)malloc(3*sizeof(int));
(*matrix)[1] = (int*)malloc(3*sizeof(int));
}


Could you, please, consider learning C *before* continuing to post in this
newsgroup?

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #13
> Could you, please, consider learning C *before* continuing to post in this
newsgroup?


ok iam so sorry, as i said my code was untested. at least i tried to help.

--
cody

[Freeware, Games and Humor]
www.deutronium.de.vu || www.deutronium.tk
Nov 13 '05 #14
In <bm************@ID-176797.news.uni-berlin.de> "cody" <do*********************@gmx.de> writes:
Could you, please, consider learning C *before* continuing to post in this
newsgroup?


ok iam so sorry, as i said my code was untested. at least i tried to help.


I can't see how such a thoroughly broken piece of code could help anyone.
First, learn C yourself and *only* then try to help other people. Tested
or not, your code clearly demonstrates your incompetence on C programming
issues.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

19
by: john smith | last post by:
Can someone please explain to me what is happening when I do a malloc(0). This is what I did. int* p = (int*)malloc(0); Then I printed the value of p and of course it was non-null. But...
34
by: Richard Hunt | last post by:
I'm sorry for asking such a silly question, but I can't quite get my head around malloc. Using gcc I have always programmed in a lax C/C++ hybrid (which I suppose is actually c++). But I have...
231
by: Brian Blais | last post by:
Hello, I saw on a couple of recent posts people saying that casting the return value of malloc is bad, like: d=(double *) malloc(50*sizeof(double)); why is this bad? I had always thought...
7
by: Rano | last post by:
/* Hello, I've got some troubles with a stupid program... In fact, I just start with the C language and sometime I don't understand how I really have to use malloc. I've readden the FAQ...
20
by: spasmous | last post by:
main() { float * f; initialize_f(f); // ...use f for processing free(f); }
15
by: Martin Jørgensen | last post by:
Hi, I have a (bigger) program with about 15-30 malloc's in it (too big to post it here)... The last thing I tried today was to add yet another malloc **two_dimensional_data. But I found out that...
68
by: James Dow Allen | last post by:
The gcc compiler treats malloc() specially! I have no particular question, but it might be fun to hear from anyone who knows about gcc's special behavior. Some may find this post interesting;...
40
by: Why Tea | last post by:
What happens to the pointer below? SomeStruct *p; p = malloc(100*sizeof(SomeStruct)); /* without a cast */ return((void *)(p+1)); /* will the returned pointer point to the 2nd...
71
by: desktop | last post by:
I have read in Bjarne Stroustrup that using malloc and free should be avoided in C++ because they deal with uninitialized memory and one should instead use new and delete. But why is that a...
23
by: raphfrk | last post by:
I am having an issue with malloc and gcc. Is there something wrong with my code or is this a compiler bug ? I am running this program: #include <stdio.h> #include <stdlib.h> typedef...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.