Why Segmentation fault in malloc( ) after calling several realloc( )?

I

I_have_nothing

Hi!
I am new in C. I try to use dynamical allocation fuction malloc( ) and
realloc( ).
I found something strange.
After several calling realloc( ), the malloc( ) will give me a
Segmentation fault.
If I just call realloc( ) once before calling malloc( ), it is OK.
Why?

I am trying to read some double-typed items from infile and save them
to c_buf.
Only when reaching EOF then I know the num_of_item = 50 (in
infile).
In the following codes at the bottom
If I use initial value size_for_n = 60, my code is ok
but if I size_for_n = 10 as initial value,
I will have Segmentation fault later when I call malloc().
I am using GCC on Linux machine.

My code is :

int num_of_item = 0;

int size_for_n = 10 ;
// int size_for_n = 60 OK, size_for_n = 10 is NG ;

fprintf (stderr,"Allocating memory for c_buf[%d]\n",size_for_n);
c_buf = ( double * ) malloc( size_for_n * sizeof(double));

if ( c_buf == NULL ) {
fprintf (stderr,
"Could not allocate memory for c_buf[%d]\n",size_for_n);
goto TERMINATE;
};



while(! EOF )
{
num_of_item++;
read_one_more_item(infile);


if ( num_of_item > size_for_n) ) {
size_for_n *= 2;
c_buf = ( double * )
realloc( (void *)c_buf, size_for_n * sizeof(double));


fprintf (stderr,
"Trying to re-allocating memory for
c_buf[%d]!\n",size_for_n);
if ( c_buf == NULL ) {

fprintf (stderr,
"Re-allocating memory for c_buf[%d]
fails!\n",size_for_n);

goto TERMINATE;

};
}
}
global_n = num_of_item;

// reallocating exact memory to c_buf[ ]
c_buf = ( double * ) realloc( (void *)c_buf, global_n *
sizeof(double));
fprintf (stderr,
"Finalizing in re-allocating memory for c_buf[%d]!\n",global_n
);
if ( c_buf == NULL ) {
fprintf (stderr,"Re-allocating memory for c_buf[%d]
fails!\n",global_n );
exit(-1);
}
....
....(codes omited)

int *p_int ; // local
....

global_m = 9000.
// global_m's value is derived in the (codes omited) part
above

fprintf (stderr,"Assigning memory.\n");

fprintf (stderr,"0 Assigning rmatbeg memory. %d\n", global_m ) ;
p_int = ( int * ) malloc( global_m * sizeof(int));
fprintf (stderr,"1 Assigning rmatbeg memory.\n") ;


if ( p_int == NULL ) {

fprintf (stderr,

"Could not allocate memory for
a_polytope.rmatbeg[%d].\n",global_m);

exit(-1);

};
fprintf (stderr,"2 Assigning rmatbeg memory.\n") ;

//int *a_polytope.rmatbeg decalred earlier as global
aa_polytope.rmatbeg = p_int ;


My output shows "Segmentation fault" when size_for_n = 10
:
Allocating memory for c_buf[10]
Trying to re-allocating memory for c_buf[20]!
Trying to re-allocating memory for c_buf[40]!
Trying to re-allocating memory for c_buf[80]!
Finalizing in re-allocating memory for c_buf[50]!
Assigning memory.
0 Assigning rmatbeg memory. 9000
Segmentation fault



My output is ok when size_for_n = 60
:
Allocating memory for c_buf[60]
Finalizing in re-allocating memory for c_buf[50]!
Assigning memory.
0 Assigning rmatbeg memory. 9000
1 Assigning rmatbeg memory.
2 Assigning rmatbeg memory.


Thanks!
 
K

Keith Thompson

I_have_nothing said:
I am new in C. I try to use dynamical allocation fuction malloc( ) and
realloc( ).
I found something strange.
After several calling realloc( ), the malloc( ) will give me a
Segmentation fault.
If I just call realloc( ) once before calling malloc( ), it is OK.
Why?

I am trying to read some double-typed items from infile and save them
to c_buf.
Only when reaching EOF then I know the num_of_item = 50 (in
infile).
In the following codes at the bottom
If I use initial value size_for_n = 60, my code is ok
but if I size_for_n = 10 as initial value,
I will have Segmentation fault later when I call malloc().
I am using GCC on Linux machine.

My code is :


[snip]

You're doing something that invokes undefined behavior. I can't guess
what it is, because you haven't shown us the actual code that you're
compiling, only some fragments of it.

Trim your program down to a small complete compilable program that
exhibits the problem. The "complete" and "compilable" parts are
critical; if it's not something we can try ourselves, it's not likely
to do much good (no "..."s unless you're declaring a variadic
function). The "small" part is less critical, but try to make it as
small as you can.

I took a quick look at what you posted and didn't see anything
obvious. It's quite possible that the problem is in the part you
didn't post.

In the process of trimming down the program, you might find the
problem yourself. If not, feel free to post again.

A couple of suggestions:

Don't cast the result of malloc() or realloc(). Both functions return
void*, which can be implicitly converted to the target pointer type.
If the compiler complains, either you're using a C++ compiler or you
forgot the required "#include <stdlib.h>". In the latter case,
putting the cast back in will make the compiler stop complaining, but
it's like disconnecting a warning light.

Assigning the result of realloc() back to the pointer being
reallocated is frowned on. For example:

ptr = malloc(100);
if (ptr == NULL) { /* handle the error */ }
ptr = realloc(ptr, 200);

If the realloc() fails, it will return a null pointer, but it will
leave the original allocated block alone. By assigning the result
directly to ptr before checking for errors, you lose the only
reference you had to the original block. If the only error handling
you're going to do in this case is to immediately abort the program,
that probably doesn't matter.

The only portable arguments to exit() are 0, EXIT_SUCCESS, and
EXIT_FAILURE. The latter are macros defined in <stdlib.h>, which you
need to #include if you're going to call exit() anyway.
 
E

Emmanuel Delahaye

I_have_nothing wrote on 11/06/05 :

This works... Stay simple and avoid those globals and gotos... Fell
free to ask for explanations (dunno your actual skills).

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

int main (void)
{
size_t num_of_item = 0;
size_t size_for_n = 10;
// int size_for_n = 60 OK, size_for_n = 10 is NG ;

fprintf (stderr
,"Allocating memory for c_buf[%d]\n"
,size_for_n);
{
double *c_buf = malloc (size_for_n * sizeof *c_buf);

if (c_buf == NULL)
{
fprintf (stderr
,"Could not allocate memory for c_buf[%d]\n"
,size_for_n);
}
else
{
int err = 0;

while (!err && num_of_item < 10000000ul)
{
num_of_item++;

if (num_of_item > size_for_n)
{
size_for_n *= 2;
void *tmp = realloc (c_buf, size_for_n * sizeof *c_buf);

fprintf (stderr
,"Trying to re-allocating memory for
c_buf[%d]!\n"
,size_for_n);

if (tmp == NULL)
{
fprintf (stderr
,"Re-allocating memory for c_buf[%d]
fails!\n"
,size_for_n);
free (c_buf), c_buf = NULL;
err = 1;
}
else
{
c_buf = tmp;
}
}
}

if (!err)
{
int global_n = num_of_item;

// reallocating exact memory to c_buf[ ]
void *tmp = realloc (c_buf, global_n * sizeof *c_buf);

fprintf (stderr
,"Finalizing in re-allocating memory for
c_buf[%d]!\n"
,global_n);

if (tmp == NULL)
{
fprintf (stderr
,"Re-allocating memory for c_buf[%d] fails!\n"
,global_n);
free (c_buf), c_buf = NULL;
}
else
{
int global_m = 9000;
// global_m's value is derived in the (codes omited)
part above

c_buf = tmp;

fprintf (stderr, "Assigning memory.\n");

fprintf (stderr, "0 Assigning rmatbeg memory. %d\n",
global_m);
int *p_int = malloc (global_m * sizeof *p_int);
fprintf (stderr, "1 Assigning rmatbeg memory.\n");

if (p_int == NULL)
{

fprintf (stderr
,"Could not allocate memory for
a_polytope.rmatbeg[%d].\n"
,global_m);
}
else
{
fprintf (stderr, "2 Assigning rmatbeg memory.\n");
}

/* when finished */
free (p_int), p_int = NULL;
}
}
free (c_buf), c_buf = NULL;
/* when finished */
}
}
return 0;
}

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"C is a sharp tool"
 
A

Al Bowers

I_have_nothing said:
Hi!
I am new in C. I try to use dynamical allocation fuction malloc( ) and
realloc( ).
I found something strange.
After several calling realloc( ), the malloc( ) will give me a
Segmentation fault.
If I just call realloc( ) once before calling malloc( ), it is OK.
Why?

I am trying to read some double-typed items from infile and save them
to c_buf.


........ code snipped ..........

The code is not complete making detection of the fault difficult.
The code indicates that you are executing the array in chunks
in a way more involved than neccessary. For example, you do not
need to use the malloc and realloc functions in combination.
Just use function realloc in a loop that reallocs when
addition storage is needed. I typically use the '%' operator
in detecting the need for additional storage.

Example:

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

int main(void)
{
double *c_buf = NULL; /* No array of doubles */
int num_of_item = 0; /* and no nr of items */
int size_for_n = 10 ; /* Allocate in chunks */
int i;
FILE *fp;

if((fp = fopen("Data.txt","r")) != NULL)
{
double d, *tmp;
for( ; (1 == fscanf(fp,"%lf",&d)); num_of_item++)
{
if(num_of_item % size_for_n == 0)
{
tmp = realloc(c_buf,
(num_of_item+size_for_n)*sizeof *tmp);
if(tmp == NULL)
{
puts("Memory allocation failure");
break;
}
c_buf = tmp;
}
c_buf[num_of_item] = d;
}
fclose(fp);
}
else puts("Unable to open file");
for(i = 0; i < num_of_item;i++)
printf("c_buf[%d] = %f\n",i,c_buf);
free(c_buf);
c_buf = NULL; /* reset in case you want to build */
num_of_item = 0; /* another array */
return 0;
}
 
C

CBFalconer

Emmanuel said:
I_have_nothing wrote on 11/06/05 :

This works... Stay simple and avoid those globals and gotos... Fell
free to ask for explanations (dunno your actual skills).

Amazing! You had the patience to extract something meaningful out
of that horrible incomplete mishmash. I think you have too much
time on your hands :)
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top