August 18, 2015 Re: Safely extend the size of a malloced memory block after realloc | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On Tuesday, 18 August 2015 at 05:51:36 UTC, Benjamin Thaut wrote:
> I specifically asked for the case where the pointer doesn't change. Obvisouly the case where it does change is easy, you first add the new range and then remove the old one. But if you do this and the pointer didn't change, the addRange doesn't do anything because its a duplicate and the removeRange then removes the range, because the pointer is still the same. You then end up with the GC not knowing anything about the range anymore.
May be implementing something like GC.resizeRange() will resolve such type of problem. Is it good idea or no?
| |||
August 19, 2015 Re: Safely extend the size of a malloced memory block after realloc | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Benjamin Thaut | On 8/18/15 1:51 AM, Benjamin Thaut wrote: > On Monday, 17 August 2015 at 19:38:21 UTC, Steven Schveighoffer wrote: >> On 8/17/15 3:27 PM, Benjamin Thaut wrote: >>> Consider the following code >>> >>> void* mem = malloc(500); >>> GC.addRange(mem, 500); >>> mem = realloc(mem, 512); // assume the pointer didn't change >>> GC.removeRange(mem); >> >> This is actually unsafe, you have to remove the range first, or else >> if it *does* change the pointer, your GC is using free'd memory. Plus, >> if it does change the pointer, how do you remove the original range? > > I specifically asked for the case where the pointer doesn't change. > Obvisouly the case where it does change is easy, you first add the new > range and then remove the old one. But if you do this and the pointer > didn't change, the addRange doesn't do anything because its a duplicate > and the removeRange then removes the range, because the pointer is still > the same. You then end up with the GC not knowing anything about the > range anymore. In the case where the pointer changes, you are in trouble. The original memory is now free, which means it can be overwritten by something else (either the C heap or some other thread that reallocates it). Then if your GC runs *before* you have added the new memory, it may collect the now-no-longer-referred-to data. It's no different than your original situation. I actually think the case where the pointer changes is worse. >> >>> // if the GC kicks in here we're f***** >>> GC.addRange(mem, 512); >> >> Can't you GC.disable around this whole thing? >> > > Yes, this would work, but It seems kind of broken to me, that you have > to make 4 API Calls to the gc to handle something as simple as a realloc. First measure code in terms of correctness, before anything else. This is neither a "simple" situation, nor a common one -- the more obscure you get, the more low level you need to write your code. It may come down to the conclusion that using realloc for this just isn't a good idea, use something else. Also, I note that others have said one can call GC.collect from another thread, which is true. One could call GC.enable as well. If you have concerns of this happening (i.e. you don't control all the code, and think your code may coexist with something that calls GC.collect), the likely correct mechanism is to take the GC global lock while doing your operation. I'm not sure if you can do that via the current API, you may have to add such a feature. -Steve | |||
August 19, 2015 Re: Safely extend the size of a malloced memory block after realloc | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Wednesday, 19 August 2015 at 14:45:31 UTC, Steven Schveighoffer wrote: > > In the case where the pointer changes, you are in trouble. The original memory is now free, which means it can be overwritten by something else (either the C heap or some other thread that reallocates it). Then if your GC runs *before* you have added the new memory, it may collect the now-no-longer-referred-to data. It's no different than your original situation. > > I actually think the case where the pointer changes is worse. Yes I made the same observation in the meantime. > > Also, I note that others have said one can call GC.collect from another thread, which is true. One could call GC.enable as well. If you have concerns of this happening (i.e. you don't control all the code, and think your code may coexist with something that calls GC.collect), the likely correct mechanism is to take the GC global lock while doing your operation. I'm not sure if you can do that via the current API, you may have to add such a feature. > Yes I figured as much. The entire purpose of this thraed was to point out that you can not safely forward a realloc to the GC. Unfortunately its not a option not to use realloc as I'm binding some code I don't have control over. To summarize the entire issue and a possible solutions I created the following ticket: https://issues.dlang.org/show_bug.cgi?id=14934 Kind Regards Benjamin Thaut | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply