freeing memory

F

Frank Silvermann

/* partition2.c */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
#define ITERATIONS 10

int rand_in_range(int, int);
int * partition(int, int);

int main(void)
{
int m=8, n=3, i;
int *p;
/* all declarations in main need to be north of here */
/* seed timer */
srand(time(NULL));
/* call partition and examine returns */
printf("set has %d elements and %d partitions\n", m, n);
for(i = 0; i < ITERATIONS; i++)
{
p = malloc((n)*sizeof(int));
p = partition(m,n);
printf("m in n chunks: %d %d %d\n", p[0], p[1], p[2]);
/* free p; */
}
return 0;
}


int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}
roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}

int * partition(int m, int n)
{
int top_range, i, p;
int *q;
/* end declarations */
/* if n>m bomb out */
if (n > m) return NULL;
top_range = m - n;
q = malloc((n)*sizeof(int));
for (i=0; i<(n-1); i++)
{
p=rand_in_range(0, top_range);
q = p + 1;
top_range = top_range - p;
}
q[n-1]=top_range + 1;
return q;
}
/* end source */
I ask my compiler to carve out memory in main and in a subroutine. The
adage is that if one asks an OS for memory, he must give it back. I
would think that the requested memory in the subroutine would disappear
when the return is made. It would also seem that I've created a memory
leak in main, but when I add a free where it is now commented out, I get
an error. Happy for any hints. frank
 
S

SM Ryan

# I ask my compiler to carve out memory in main and in a subroutine. The
# adage is that if one asks an OS for memory, he must give it back. I
# would think that the requested memory in the subroutine would disappear
# when the return is made. It would also seem that I've created a memory

What makes heap memory like malloc so useful is precisely that the
memory is not automatically released when a procedure returns. The
normal C malloc does not garbage collect, so it is your responsibility
to keep a pointer to each mallocked block until you free it, and not
to use the pointer after free.
 
J

jackdorse

Frank said:
/* partition2.c */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define SWAP(m, n) (tmp = (m), (m) = (n), (n) = tmp)
#define ITERATIONS 10

int rand_in_range(int, int);
int * partition(int, int);

int main(void)
{
int m=8, n=3, i;
int *p;
/* all declarations in main need to be north of here */
/* seed timer */
srand(time(NULL));
/* call partition and examine returns */
printf("set has %d elements and %d partitions\n", m, n);
for(i = 0; i < ITERATIONS; i++)
{
p = malloc((n)*sizeof(int));
p = partition(m,n);
printf("m in n chunks: %d %d %d\n", p[0], p[1], p[2]);
/* free p; */
}
return 0;
}


int rand_in_range(int m, int n)
{
/*seed srand in main */
/* [m, n] is range */
int roll_again_threshold, divisor, result, tmp, offset, num_results;

if (m>n) SWAP(m, n);
offset = m;
num_results = n - m + 1;

if (num_results == 1) {
return m;
}
roll_again_threshold = RAND_MAX - RAND_MAX%num_results;
divisor = roll_again_threshold/num_results;

do {
result = rand();
} while (result >= roll_again_threshold);
result /= divisor;
return offset + result;
}

int * partition(int m, int n)
{
int top_range, i, p;
int *q;
/* end declarations */
/* if n>m bomb out */
if (n > m) return NULL;
top_range = m - n;
q = malloc((n)*sizeof(int));
for (i=0; i<(n-1); i++)
{
p=rand_in_range(0, top_range);
q = p + 1;
top_range = top_range - p;
}
q[n-1]=top_range + 1;
return q;
}
/* end source */
I ask my compiler to carve out memory in main and in a subroutine. The
adage is that if one asks an OS for memory, he must give it back. I
would think that the requested memory in the subroutine would disappear
when the return is made. It would also seem that I've created a memory
leak in main, but when I add a free where it is now commented out, I get
an error. Happy for any hints. frank





it should be

free(p);
 
F

Frank Silvermann

Chris said:
Frank Silvermann wrote:

{
p = malloc((n)*sizeof(int));

Allocate some memory [1] ...
p = partition(m,n);

.... and then immediately make it inaccessible.

Easy fix: remove the mallocation.
/* free p; */

free( p );
Thanks all for replies. Apparently the parens matter. Here is my new
version of main, with everything else unchanged from upthread:
int main(void)
{
int m=8, n=3, i, j;
int *p;
/* all declarations in main need to be north of here */
/* seed srand with time */
srand(time(NULL));
/* call partition and examine returns */
printf("set has %d elements and %d partitions\n", m, n);
for(i = 0; i < ITERATIONS; i++)
{
p = malloc((n)*sizeof(int));
p = partition(m,n);
if (p = NULL)
{
printf("failure\n");
}
printf("m in n chunks: ");
/*for (j = 0;j < n; j++)
{
printf(" %d", p[j]);
}
printf("\n");*/
free (p);
}
return 0;
}
/*end source */
Couple of questions: 1) Do I have a memory leak?
2) The output is now commented out. It compiles but causes my OS to
hang. I could send the error report and wait for the Unnamed Vendor to
get back to me, but I'm not sure when hell is to freeze over. Anyways,
besides the fact that the commented-out source doesn't produce behavior
in the ensuing executable that I like, it looks childish, in particular
in a language that was designed to hop around arrays. So this question
is, what is an elegant way in C to print a smallish array of ints? frank
 
K

Keith Thompson

Frank Silvermann said:
Chris said:
Frank said:
{
p = malloc((n)*sizeof(int));
Allocate some memory [1] ...
p = partition(m,n);
.... and then immediately make it inaccessible.
Easy fix: remove the mallocation.
/* free p; */
free( p );
Thanks all for replies. Apparently the parens matter.

Of course they do. free is a function, the parentheses are part of
the syntax of a function call. (Note that return is a special kind of
statement, *not* a function; its syntax is "return;" or
"return expression;", so no parentheses are required. Parentheses are
allowed because an expression may be enclosed in parentheses:
"return (expression);" is legal, but "return ();" is not.)
Here is my new version of main, with everything else unchanged from
upthread: [snip]
int *p; [snip]
p = malloc((n)*sizeof(int));
p = partition(m,n);
[snip]

You have a memory leak. You assign the result of malloc() to p, and
you then immediately assign another value to p, losing any reference
to the allocated memory.
 
J

Joe Smith

Keith Thompson said:
Frank Silvermann said:
Chris said:
Frank Silvermann wrote:

{
p = malloc((n)*sizeof(int));
Allocate some memory [1] ...

p = partition(m,n);
.... and then immediately make it inaccessible.
Easy fix: remove the mallocation.

/* free p; */
free( p );
Thanks all for replies. Apparently the parens matter.

Of course they do. free is a function, the parentheses are part of
the syntax of a function call. (Note that return is a special kind of
statement, *not* a function; its syntax is "return;" or
"return expression;", so no parentheses are required. Parentheses are
allowed because an expression may be enclosed in parentheses:
"return (expression);" is legal, but "return ();" is not.)
Why do people put whitespace between the ultimate 'e' and '(' ?

Here is my new version of main, with everything else unchanged from
upthread: [snip]
int *p; [snip]
p = partition(m,n);
[snip]

You have a memory leak. You assign the result of malloc() to p, and
you then immediately assign another value to p, losing any reference
to the allocated memory.
I believe that if I remove:
p = malloc((n)*sizeof(int));
I might be better off. Furthermore, I suspect that the reason the ensuing
/*for (j = 0;j < n; j++)
{
printf(" %d", p[j]);
}
printf("\n");*/
was in trouble was that I had lost any reference to the allocated memory.
frank
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top