|
From: Carlos d. M. <cg...@wo...> - 2002-09-03 12:03:49
|
Hi: I got a C library reference from cplusplus.com, and in realloc there is something I'm not sure about. There it is said that after the call to realloc, this function returns a pointer to the new allocated memory or NULL if failed, and that the original pointer provided to it as the first parameter is left untouched. In their example they write: numbers = (int*)realloc(numbers, newsize); That made me think, if the pointer provided is left untouched, and in case of error it returns NULL; it wouldn't be a bad programming practice use the same pointer as the parameter and the returning value? Could it generate a memory leak? Perhaps that means that after the call you have two allocated memory blocks, one of the previous size and another with the new size, if you use the same pointer as parameter and return value then either if it succeds or not you'll get a memory block which won't be freed and will behave badly, so you'll need to free it manually 8which seems a little bad feature, at least when the call succeeds), and if it fails you either lose a chance to recover with the original pointer (would be nice only if it fails). But then I made a little experiment for see this. I made more or less this code: int* bufferone, *buffertwo; bufferone = (int*)malloc(2 * sizeof(int)); for(int i = 0; i < 2; i++) bufferone[i] = i + 1; for[] cout bufferone[i]; buffertwo = (int*)realloc(bufferone, 4 * sizeof(int)); cout << bufferone << " " << buffertwo << endl; for[] buffertwo[i] = i + 1; for[] cout << bufferone[i]; for[] cout << buffertwo[i]; free(bufferone); fors for cout; free(buffertwo) again the for couts. After realloc, bufferone : 1 2; buffertwo: 1, 2, 3, 4. The same address for both. After free(bufferone) bufferone: 0, 2; buffertwo: 0, 2, 3, 4. After free(buffertwo) bufferone: 49855478, 2; buffertwo: 49855478, 2, 3, 4. Or different addresses: before frees and after realloc bufferone has been freed, and bufferone[0] is 48716817 (any number), then after free(bufferone) bufferone[0] has 4816871687, and buffertwo[0] has 1; and after free(buffertwo) bufferone[0] has 4816871687 and buffertwo[0] has 0. If I use realloc(buffertwo, 0); then the value stored in the direction where the pointer pointed to as the first member of the array is left untouched, buffertwo[0] gives 1. If I use buffertwo = (int*)realloc(buffertwo, 0); then the program is closed by windows with its classic dialog, this program has to been closed. So I deduce, you can do numbers = (int*)realloc(numbers, newsize); because what pointer as parameter being untouched means seems to be: the value of it, the direction to which it points to is the same, but the memory it points to is either increased, or moved and freed in that point, so after the call you won't can use it, at least if it succeeds, and I'd bet that neither it is useful if it fails, which I think makes more sense. |
|
From: Ioannis V. <no...@ho...> - 2002-09-03 13:42:26
|
> -----Original Message----- > From: dev...@li...=20 > [mailto:dev...@li...] On Behalf=20 > Of Carlos Garc=EDa del Monte > Sent: Tuesday, September 03, 2002 3:03 PM > To: dev-cpp-users-list > Subject: [Dev-C++] realloc >=20 >=20 > Hi: > I got a C library reference from cplusplus.com, and in=20 > realloc there is > something I'm not sure about. > There it is said that after the call to realloc, this=20 > function returns a > pointer to the new allocated memory or NULL if failed, and that the > original pointer provided to it as the first parameter is left > untouched. In their example they write: > numbers =3D (int*)realloc(numbers, newsize); > [...] DON'T USE MALLOC()/CALLOC()/REALLOC() IN C++ PROGRAMS! ONLY IN C. In C++ use new/new[]/delete/delete[] and standard containers. "[diff.malloc] C.2.4.2 Memory allocation functions 1 The functions calloc, malloc, and realloc are restricted in this International Standard. 20.4.6 describes the changes." Now regarding realloc(): If it manages to change the size at the current location it returns the same pointer you passed to it. If it allocates space somewhere else, it moves the contents there and frees the current space. In case it fails, it returns NULL and the current memory address remains unchanged. In summary, if it fails you have the old memory area. If it doesn't fail use the returned pointer and forget the old one. Example: /* C code */ int *p=3Dmalloc(100*sizeof(*p)); int *r=3Drealloc(p, 120*sizeof(*r)); if(!r) /* use the old p */ /* use the new r and forget p address */ Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.cjb.net * Alternative URL: http://run.to/noicys |
|
From: Carlos d. M. <cg...@wo...> - 2002-09-03 16:22:50
|
>
>
> DON'T USE MALLOC()/CALLOC()/REALLOC() IN C++ PROGRAMS! ONLY IN C.
WITH ALL THE HIGHLIGHTED WORDS MALLOC FOR C, NEW FOR C++ (WITH THE
CORRESPONDENT "LIBERATORS")
> Now regarding realloc():
>
> If it manages to change the size at the current location it returns the
> same pointer you passed to it. If it allocates space somewhere else, it
> moves the contents there and frees the current space. In case it fails,
> it returns NULL and the current memory address remains unchanged.
>
> In summary, if it fails you have the old memory area. If it doesn't fail
> use the returned pointer and forget the old one. Example:
>
> /* C code */
>
> int *p=malloc(100*sizeof(*p));
>
> int *r=realloc(p, 120*sizeof(*r));
>
> if(!r)
> /* use the old p */
>
> /* use the new r and forget p address */
I tried to make an example reasigning to a so big block that it couldn't be
succeeding (I did something like realloc(pointer,
15545454554545455454545454554545); but then windows closed the console, and
I couldn't see the result.
So, in the end, just what I feared at first, but couldn't prove the second
part with the experiment:
numbers = (int*)realloc(numbers, newsize);
is a practice better to avoid. Because if it fails then you get a block of
memory which had been allocated , but not freed. so
if(!r){
[...]
free(p);
}
>
>
> Ioannis
>
> * Ioannis Vranos
> * Programming pages: http://www.noicys.cjb.net
> * Alternative URL: http://run.to/noicys
>
> -------------------------------------------------------
> This sf.net email is sponsored by: OSDN - Tired of that same old
> cell phone? Get a new here for FREE!
> https://www.inphonic.com/r.asp?r=urceforge1&refcode1=vs3390
> _______________________________________________
> Dev-cpp-users mailing list
> Dev...@li...
> TO UNSUBSCRIBE: http://www.noicys.cjb.net/devcpp/ub.htm
> https://lists.sourceforge.net/lists/listinfo/dev-cpp-users
|
|
From: Abhijit S. <mu...@gm...> - 2002-09-03 17:03:09
|
Greets, Carlos.
----- Original Message -----
DON'T USE MALLOC()/CALLOC()/REALLOC() IN C++ PROGRAMS! ONLY IN C.
WITH ALL THE HIGHLIGHTED WORDS MALLOC FOR C, NEW FOR C++ (WITH THE
CORRESPONDENT "LIBERATORS")
Now regarding realloc():
If it manages to change the size at the current location it returns the
same pointer you passed to it. If it allocates space somewhere else, it
moves the contents there and frees the current space. In case it fails,
it returns NULL and the current memory address remains unchanged.
In summary, if it fails you have the old memory area. If it doesn't fail
use the returned pointer and forget the old one. Example:
/* C code */
int *p=malloc(100*sizeof(*p));
int *r=realloc(p, 120*sizeof(*r));
if(!r)
/* use the old p */
/* use the new r and forget p address */
I tried to make an example reasigning to a so big block that it couldn't be
succeeding (I did something like realloc(pointer,
15545454554545455454545454554545); but then windows closed the console, and
I couldn't see the result.
So, in the end, just what I feared at first, but couldn't prove the second
part with the experiment:
numbers = (int*)realloc(numbers, newsize);
is a practice better to avoid. Because if it fails then you get a block of
memory which had been allocated , but not freed. so
------------------------------
Then maybe this?
char *ptr, *tmp_ptr;
int buf_size = BUF_SIZE;
*ptr = (char *)malloc(BUF_SIZE); // Assuming success
*tmp_ptr = realloc(ptr, NEW_BUF_SIZE);
if(tmp_ptr)
{
free(ptr);
ptr = tmp_ptr;
tmp_ptr = NULL;
buf_size = NEW_BUF_SIZE;
}
___________________________________________________________
Abhijit Shylanath
E-mail: mu...@gm... || ibr...@bi...
Web-site: http://mudeth.tripod.com/
|
|
From: Ioannis V. <no...@ho...> - 2002-09-03 18:27:33
|
> -----Original Message-----
> From: dev...@li...=20
> [mailto:dev...@li...] On Behalf=20
> Of Abhijit Shylanath
> Sent: Tuesday, September 03, 2002 7:58 PM
> To: Carlos Garc=EDa del Monte; dev-cpp-users-list
> Subject: Re: [Dev-C++] realloc
>=20
> Then maybe this?
>=20
> char *ptr, *tmp_ptr;
> int buf_size =3D BUF_SIZE;
>=20
> *ptr =3D (char *)malloc(BUF_SIZE); // Assuming success
> *tmp_ptr =3D realloc(ptr, NEW_BUF_SIZE);
> if(tmp_ptr)
> {
> free(ptr);
This is an error. If (tmp_ptr) means if realloc() succedeed. In this
case ptr has already been freed.
Ioannis
* Ioannis Vranos
* Programming pages: http://www.noicys.cjb.net
* Alternative URL: http://run.to/noicys
|
|
From: Carlos d. M. <cg...@wo...> - 2002-09-03 19:09:00
|
The point is that with realloc, if it succeeds the original memory pointe=
d by
the argument pointer is freed and so you can forget it and work with the =
new,
but if it fails, then the memory pointed to by the argument pointer remai=
ns
valid, and if you use that same pointer as return value, then you get tha=
t the
pointer is no more pointing to that piece of still valid memory, and, how=
you
free it? it will be annoying your program.
The moral of the story is, don't use the same pointer as argument and ret=
urn
value of realloc.
If it fails, if(!returnpointer) work with the original and free(original)
if it succeeds else work with the new and forget the old.
Abhijit Shylanath escribi=F3:
> Greets, Carlos.
>
> ----- Original Message -----
>
> DON'T USE MALLOC()/CALLOC()/REALLOC() IN C++ PROGRAMS! ONLY IN C.
> WITH ALL THE HIGHLIGHTED WORDS MALLOC FOR C, NEW FOR C++ (WITH THE
> CORRESPONDENT "LIBERATORS")
> Now regarding realloc():
> If it manages to change the size at the current location it returns the
> same pointer you passed to it. If it allocates space somewhere else, it
> moves the contents there and frees the current space. In case it fails,
> it returns NULL and the current memory address remains unchanged.
> In summary, if it fails you have the old memory area. If it doesn't fai=
l
> use the returned pointer and forget the old one. Example:
> /* C code */
> int *p=3Dmalloc(100*sizeof(*p));
> int *r=3Drealloc(p, 120*sizeof(*r));
> if(!r)
> /* use the old p */
> /* use the new r and forget p address */
> I tried to make an example reasigning to a so big block that it couldn'=
t be
> succeeding (I did something like realloc(pointer,
> 15545454554545455454545454554545); but then windows closed the console,=
and
> I couldn't see the result.
> So, in the end, just what I feared at first, but couldn't prove the sec=
ond
> part with the experiment:
> numbers =3D (int*)realloc(numbers, newsize);
> is a practice better to avoid. Because if it fails then you get a block=
of
> memory which had been allocated , but not freed. so
>
> ------------------------------
>
> Then maybe this?
>
> char *ptr, *tmp_ptr;
> int buf_size =3D BUF_SIZE;
>
> *ptr =3D (char *)malloc(BUF_SIZE); // Assuming success
> *tmp_ptr =3D realloc(ptr, NEW_BUF_SIZE);
> if(tmp_ptr)
> {
> free(ptr);
> ptr =3D tmp_ptr;
> tmp_ptr =3D NULL;
> buf_size =3D NEW_BUF_SIZE;
> }
> ___________________________________________________________
>
> Abhijit Shylanath
>
> E-mail: mu...@gm... || ibr...@bi...
> Web-site: http://mudeth.tripod.com/
|
|
From: Abhijit S. <mu...@gm...> - 2002-09-05 16:19:28
|
----- Original Message ----- From: "Carlos García del Monte" <cg...@wo...> To: "dev-cpp-users-list" <dev...@li...> Sent: Wednesday, September 04, 2002 12:39 AM Subject: Re: [Dev-C++] realloc The point is that with realloc, if it succeeds the original memory pointed by the argument pointer is freed and so you can forget it and work with the new, but if it fails, then the memory pointed to by the argument pointer remains valid, and if you use that same pointer as return value, then you get that the pointer is no more pointing to that piece of still valid memory, and, how you free it? it will be annoying your program. The moral of the story is, don't use the same pointer as argument and return value of realloc. If it fails, if(!returnpointer) work with the original and free(original) if it succeeds else work with the new and forget the old. --------------------------- Yeah, sorry for the leads-to-memory-leak-type mistake (which I hate and detest and avoid at all costs :). No way under C++ to realloc() a new'ed pointer, is there? (Apart from writing your own `renew' function) ___________________________________________________________ Abhijit Shylanath E-mail: mu...@gm... || ibr...@bi... Web-site: http://mudeth.tripod.com/ |
|
From: Ioannis V. <no...@ho...> - 2002-09-05 16:47:15
|
-----Original Message----- > From: dev...@li...=20 > [mailto:dev...@li...] On Behalf=20 > Of Abhijit Shylanath > Sent: Thursday, September 05, 2002 7:15 PM > To: Carlos Garc=EDa del Monte; dev-cpp-users-list > Subject: Re: [Dev-C++] realloc >=20 > No way under C++ to=20 > realloc() a new'ed > pointer, is there? (Apart from writing your own `renew' function) In C++ standard library containers must be preferred instead of manually allocating and deallocating memory on the free store. No realloc() feature is provided as stand alone. Take also a look at: http://www.research.att.com/~bs/bs_faq2.html#renew Ioannis * Ioannis Vranos * Programming pages: http://www.noicys.cjb.net * Alternative URL: http://run.to/noicys |
|
From: Ioannis V. <no...@ho...> - 2002-09-03 18:24:59
|
-----Original Message-----
From: dev...@li...
[mailto:dev...@li...] On Behalf Of Carlos
Garc=EDa del Monte
Sent: Tuesday, September 03, 2002 7:23 PM
To: dev-cpp-users-list
Subject: Re: [Dev-C++] realloc =20
I tried to make an example reasigning to a so big block that it couldn't
be succeeding (I did something like realloc(pointer,
15545454554545455454545454554545); but then windows closed the console,
and I couldn't see the result.=20
So, in the end, just what I feared at first, but couldn't prove the
second part with the experiment:=20
numbers =3D (int*)realloc(numbers, newsize); =20
=20
The casting is redundant (always speaking of C).
=20
=20
is a practice better to avoid. Because if it fails then you get a block
of memory which had been allocated , but not freed. =20
=20
For accuracy, if it fails you remain with the old allocated memory.
=20
so=20
if(!r){=20
[...]=20
free(p);=20
} =20
=20
Ioannis
* Ioannis Vranos
* Programming pages: http://www.noicys.cjb.net
<http://www.noicys.cjb.net/>=20
* Alternative URL: http://run.to/noicys
|