strange behaviour of realloc()

D

diegotorquemada

Hello,

As far as I understand realloc() should not modify the old array, however this does not seem to happen:

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

int main(void)
{
int *p, i;
size_t size=0;

printf("Size of the vector: ");
scanf("%d", &size);

p = (int *)malloc(size*sizeof(int));
if (p==NULL)
{
perror("malloc() failed\n");
exit(EXIT_FAILURE);
}

printf("p = %p\n", p);
for(i=0; i<size; i++)
{
p = i;
printf("%d, ", p);
}
printf("\b\b.\n");

printf("Now we will duplicate the size of the list: %d\n", size);
size *= 2;
p = (int *)realloc(p, size);
if (p==NULL)
{
perror("realloc() failed\n");
exit(EXIT_FAILURE);
}

printf("p = %p\n", p);

for(i=0; i<size; i++)
printf("%d, ", p);
printf("\b\b.\n");

free(p);

return 0;
}

I compile with:
[daalvarez@earendil ~]$ gcc -Wall -o 08_realloc 08_realloc.c

And I get:
[daalvarez@earendil ~]$ ./08_realloc
Size of the vector: 10
p = 0x84e4008
0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Now we will duplicate the size of the list: 10
p = 0x84e4008
0, 1, 2, 3, 4, 25, 0, 7, 8, 9, 0, 135121, 0, 0, 0, 0, 0, 0, 0, 0.
**
||
LOOK for the 5... not it is 25


Using:
[daalvarez@earendil ~]$ gcc --version
gcc (GCC) 4.7.2
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

What am I doing wrong?

Kind regards,

Diego Andrés
 
D

Diego Andres Alvarez Marin

Stupid me... I just forgot to realloc with the proper size:

#include <stdio.h>

#include <stdlib.h>



int main(void)

{

int *p, i;

size_t size=0;



printf("Size of the vector: ");

scanf("%d", &size);



p = (int *)malloc(size*sizeof(int));

if (p==NULL)

{

perror("malloc() failed\n");

exit(EXIT_FAILURE);

}



printf("p = %p\n", p);

for(i=0; i<size; i++)

{

p = i;

printf("%d, ", p);

}

printf("\b\b.\n");



printf("Now we will duplicate the size of the list: %d\n", size);

size *= 2;

p = (int *)realloc(p, size*sizeof(int));
if (p==NULL)

{

perror("realloc() failed\n");

exit(EXIT_FAILURE);

}



printf("p = %p\n", p);



for(i=0; i<size; i++)

printf("%d, ", p);

printf("\b\b.\n");



free(p);



return 0;

}
 
J

James Kuyper

Hello,

As far as I understand realloc() should not modify the old array, however this does not seem to happen:

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

int main(void)
{
int *p, i;
size_t size=0;

printf("Size of the vector: ");
scanf("%d", &size);

p = (int *)malloc(size*sizeof(int));

That should be:
p = malloc(size * sizeof *p);

The 'int*' is unnecessary and, in C90 can actually hide the problem that
would occur if you forgot to #include <stdlib.h>. Using *p rather than
(int) makes sure that the code remains manifestly correct, even if the
type p points at were to change - you only have to examine that one line
to make sure it's correct. With the original form, you would have to
also check the definition of 'p'.
if (p==NULL)
{
perror("malloc() failed\n");
exit(EXIT_FAILURE);
}

printf("p = %p\n", p);
for(i=0; i<size; i++)
{
p = i;
printf("%d, ", p);
}
printf("\b\b.\n");

printf("Now we will duplicate the size of the list: %d\n", size);


I think you mean "double" rather than "duplicate".
size *= 2;
p = (int *)realloc(p, size);
if (p==NULL)
{
perror("realloc() failed\n");
exit(EXIT_FAILURE);
}

That should be
char *temp = realloc(p, size * sizeof *p);
if(temp==NULL)
{
perror("realloc() failed\n");
free(p);
exit(EXIT_FAILURE);
}
p = temp;

You should not store the value returned by realloc() in the only pointer
object that the original pointer value was stored in. That's because, if
the return value is a null pointer, the original pointer is still valid,
and the memory it pointed at is still allocated, and still needs to be
free()d. However, since you've replaces that pointer value with a null
pointer value, you can neither access that memory nor free() it. You've
just created a potential memory leak. That's not a problem in a tiny
program like this, but you should make using realloc() this way an
automatic habit, so you don't even have to think about it.
printf("p = %p\n", p);

for(i=0; i<size; i++)
printf("%d, ", p);
printf("\b\b.\n");

free(p);

return 0;
}

I compile with:
[daalvarez@earendil ~]$ gcc -Wall -o 08_realloc 08_realloc.c

And I get:
[daalvarez@earendil ~]$ ./08_realloc
Size of the vector: 10
p = 0x84e4008
0, 1, 2, 3, 4, 5, 6, 7, 8, 9.
Now we will duplicate the size of the list: 10
p = 0x84e4008
0, 1, 2, 3, 4, 25, 0, 7, 8, 9, 0, 135121, 0, 0, 0, 0, 0, 0, 0, 0.
**
||
LOOK for the 5... not it is 25


I see that you've already found the main problem. My comments were
mainly about peripheral issues.
 
E

Eric Sosman

Hello,

As far as I understand realloc() should not modify the old array, however this does not seem to happen:

Your code has many errors. Most are probably not important,
but one is glaringly wrong.
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
int *p, i;
size_t size=0;

printf("Size of the vector: ");

PNIP: The prompt might never appear; see the FAQ.
scanf("%d", &size);

PNIP: "%d" converts an `int' value, but `size' is a `size_t'.
PNIP: If scanf() fails, you'll never find out about it.
p = (int *)malloc(size*sizeof(int));
if (p==NULL)
{
perror("malloc() failed\n");
exit(EXIT_FAILURE);
}

printf("p = %p\n", p);

PNIP: "%p" expects a `void*', not an `int*'.
for(i=0; i<size; i++)
{
p = i;
printf("%d, ", p);
}
printf("\b\b.\n");

printf("Now we will duplicate the size of the list: %d\n", size);


PNIP: "%d" converts an `int', not a `size_t'.
size *= 2;
p = (int *)realloc(p, size);

GLARING: The second argument calls for `size' bytes, but you
need space for `size' `int's.
if (p==NULL)
{
perror("realloc() failed\n");
exit(EXIT_FAILURE);
}

printf("p = %p\n", p);

PNIP: As above.
for(i=0; i<size; i++)
printf("%d, ", p);


GLARING: Unless sizeof(int)==1, this marches off the end of
the allocated area.

PNIP: Even if sizeof(int)==1, this reads a lot of uninitialized
("indeterminate") values.
 

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

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top