Does realloc free the former buffer if it fails? - realloc

If realloc fails and returns NULL is the former buffer free'd or it is kept intact? I didn't found that particular piece of information in the man page and I'm quite unsure what to do. If memory is freed then double-free could be risky. If not then the leakage would occur.

No, it does not. That aspect has often annoyed me since you can't just use:
if ((buff = realloc (buff, newsize)) == NULL)
return;
in your code if you want to free the original on failure. Instead you have to do something like:
if ((newbuff = realloc (buff, newsize)) == NULL) {
free (buff);
return;
}
buff = newbuff;
Of course, I understand the rationale behind keeping the original buffer intact on failure but my use case has popped up enough that I generally code my own functions to handle that case, something like:
// Attempt re-allocation. If fail, free old buffer, return NULL.
static void *reallocFreeOnFail (void *oldbuff, size_t sz) {
void *newbuff = realloc (oldbuff, sz);
if (newbuff == NULL) free (oldbuff);
return newbuff;
}
// Attempt re-allocation. If fail, return original buffer.
// Variable ok is set true/false based on success of re-allocation.
static void *reallocLeaveOnFail (void *oldbuff, size_t sz, int *ok) {
void *newbuff = realloc (oldbuff, sz);
if (newbuff == NULL) {
*ok = 0;
return oldbuff;
}
*ok = 1;
return newbuff;
}
The relevant section in the C11 standard states (my italics):
7.20.3.4 The realloc function
If ptr is a null pointer, the realloc function behaves like the malloc function for the
specified size. Otherwise, if ptr does not match a pointer earlier returned by the
calloc, malloc, or realloc function, or if the space has been deallocated by a call
to the free or realloc function, the behavior is undefined. If memory for the new
object cannot be allocated, the old object is not deallocated and its value is unchanged.

realloc() returns a pointer to the newly allocated memory, which is suitably aligned for any kind of variable and may be different from ptr, or NULL if the request fails. If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned. If realloc() fails the original block is left untouched; it is not freed or moved.
malloc(3) - Linux man page

No. No change of the former buffer is done if realloc() failed.
man realloc(3):
realloc() returns a pointer to the newly allocated memory, which is suitably
aligned for any kind of variable and may be different from ptr, or NULL if the
request fails. If size was equal to 0, either NULL or a pointer suitable to be
passed to free() is returned. If realloc() fails the original block is left
untouched; it is not freed or moved.

No.It won't. Realloc changes increases/decreases the dynamic memory allocated via malloc or calloc. It will return NULL in case realloc fails while increasing memory but it won't change previously allocated memory. As Realloc computes new memory allocation from the base address of previously allocated memory, it does not perform any operation on the memory

Related

How to get COR_PRF_FUNCTION_ARGUMENT_INFO from COR_PRF_ELT_INFO using GetFunctionEnter3Info function in ICorProfilerInfo3 interface

I'm using CLR profiling API and trying to get arguments info (COR_PRF_FUNCTION_ARGUMENT_INFO) from COR_PRF_ELT_INFO using GetFunctionEnter3Info function.
Below is my code. It seems GetFunctionEnter3Info function is not setting the value for pArgumentInfo. It always has null value. However, the function returns S_OK, which is a success.
I may be missing something. How should I get COR_PRF_FUNCTION_ARGUMENT_INFO from COR_PRF_ELT_INFO ?
PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
COR_PRF_FRAME_INFO *pFrameInfo = 0;
ULONG *pcbArgumentInfo = 0;
COR_PRF_FUNCTION_ARGUMENT_INFO *pArgumentInfo = NULL;
corProfilerInfo->GetFunctionEnter3Info(functionId.functionID, eltInfo, pFrameInfo, pcbArgumentInfo, pArgumentInfo);
if(pArgumentInfo) {
//
}
}
It is a little bit tricky,
By msdn doc:
pcbArgumentInfo
[in, out] A pointer to the total size, in bytes, of the COR_PRF_FUNCTION_ARGUMENT_INFO structure (plus any additional COR_PRF_FUNCTION_ARGUMENT_RANGE structures for the argument ranges pointed to by pArgumentInfo). If the specified size is not enough, ERROR_INSUFFICIENT_BUFFER is returned and the expected size is stored in pcbArgumentInfo. To call GetFunctionEnter3Info just to retrieve the expected value for *pcbArgumentInfo, set *pcbArgumentInfo=0 and pArgumentInfo=NULL
In other words, you have a single COR_PRF_FUNCTION_ARGUMENT_INFO structure, which references multiple COR_PRF_FUNCTION_ARGUMENT_RANGE.
First of all, get a number of bytes of pcbArgumentInfo, after that allocate bytes and pass the pointer to GetFunctionEnter3Info as COR_PRF_FUNCTION_ARGUMENT_INFO.
Here is an example
PROFILER_STUB EnterStub(FunctionIDOrClientID functionId, COR_PRF_ELT_INFO eltInfo)
{
ULONG pcbArgumentInfo = 0;
COR_PRF_FRAME_INFO frameInfo;
corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, NULL);
char* pArgumentInfo = new char[pcbArgumentInfo];
corProfilerInfo3->GetFunctionEnter3Info(functionIDOrClientID.functionID, eltInfo, &frameInfo, &pcbArgumentInfo, (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo);
COR_PRF_FUNCTION_ARGUMENT_INFO* ptr = (COR_PRF_FUNCTION_ARGUMENT_INFO*)pArgumentInfo;
}
To access the second argument info block of COR_PRF_FUNCTION_ARGUMENT_RANGE use
prt->ranges[1]
The number of blocks is written in ptr->numRanges

NPAPI plug-in in safari can not call js function?

all.I want to call a js function to show something in my plugin.This is my code
NPObject* npwindow = NULL;
NPError ret = browser->getvalue(mInstanceForJS, NPNVWindowNPObject, &npwindow);
if (ret != NPERR_NO_ERROR)
return ;
// Get window object.
NPVariant windowVar;
NPIdentifier winID = browser->getstringidentifier("window");
bool bRet = browser->getproperty(mInstanceForJS, npwindow, winID, &windowVar);
if (!bRet)
{
browser->releaseobject(npwindow);
return ;
}
NPObject* window = NPVARIANT_TO_OBJECT(windowVar);
NPVariant voidResponse;
NPVariant elementId;
STRINGZ_TO_NPVARIANT([info UTF8String], elementId);
NPVariant args[] = {elementId};
NPIdentifier funcID= browser->getstringidentifier([funName UTF8String]);
bRet = browser->invoke(mInstanceForJS, window, funcID, args, 1, &voidResponse);
browser->releasevariantvalue(&windowVar);
when called bRet = browser->invoke(mInstanceForJS, window, funcID, args, 1, &voidResponse);,Safari can not responsed.Is there any errors?
npwindow is already the window object; you're effectively querying for "window.window". Granted, I don't know why this wouldn't work, but it seems a little weird.
That's problem #1.
Problem #2 is that you're using STRINGZ_TO_NPVARIANT to store the result of UTF8String. STRINGZ_TO_NPVARIANT doesn't copy the memory, so you could be in trouble if the function wanted to hang onto that string, since the string returned by that will be freed when your autorelease pool cycles. Of course, that could also be a memory leak. Either way, the correct way to pass a string to the browser is to allocate memory for it using NPN_MemAlloc and then copy the string in. Then pass that pointer to the browser. See http://npapi.com/memory for more info.
Problem #3 is that you haven't given us any idea of when you are running this code; it's quite possible that you are trying to run this code too early in the plugin or page lifecycle and thus it may not work because of that.
Then there is another question: What do you mean by "Safari can no responsed"? Forgetting the grammatical error, I'm not sure what you mean by this. Does it hang? is bRet false? Does your computer suddenly get encased in ice, thus halting all processing? If the above is not helpful, please answer these questions and I'll try again.

Battery info from the Blackberry 10 SDK

I tried this code:
battery_info_t **pointer=NULL;
battery_get_info(pointer);
return battery_info_get_time_to_empty(*pointer); // needs simple pointer (*pointer)
My question is: how can i convert **pointer to *pointer
In this usage the battery_info_... function calls take a pointer to a battery_info_t type, so you would declare pointer as that and use it as the argument to those calls. To set pointer to the correct value you pass a pointer to it to battery_get_info(). You must also free the memory allocated to pointer when you are done:
battery_info_t *pointer = NULL;
battery_get_info(&pointer);
int t = battery_info_get_time_to_empty(pointer);
battery_free_info(&pointer);
return t;
This works:
battery_info_t *pointer=NULL;
battery_get_info(&pointer);
return battery_info_get_time_to_empty(pointer);
But returns 65535, on an emulator, so i can't tell if it works or not, because i don have an BB10...

iOS - libical / const char * - memory usage

I am using the libical library to parse the iCalendar format and read the information I need out of it. It is working absolutely fine so far, but there is one odd thing concerning ical.
This is my code:
icalcomponent *root = icalparser_parse_string([iCalData cStringUsingEncoding:NSUTF8StringEncoding]);
if (root)
{
icalcomponent *currentEvent = icalcomponent_get_first_component(root, ICAL_VEVENT_COMPONENT);
while (currentEvent)
{
while(currentProperty)
{
icalvalue *value = icalproperty_get_value(currentProperty);
char *icalString = icalvalue_as_ical_string_r(value); //seems to leak
NSString *currentValueAsString = [NSString stringWithCString:icalString
encoding:NSUTF8StringEncoding];
icalvalue_free(value);
//...
//import data
//...
icalString = nil;
currentValueAsString = nil;
icalproperty_free(currentProperty);
currentProperty = icalcomponent_get_next_property(currentEvent, ICAL_ANY_PROPERTY);
} //end while
} //end while
icalcomponent_free(currentEvent);
}
icalcomponent_free(root);
//...
I did use instruments to check my memory usage and were able to find out, that this line seems to leak:
char *icalString = icalvalue_as_ical_string_r(value); //seems to leak
If I'd copy and paste this line 5 or six times my memory usage would grow about 400kb and never get released anymore.
There is no free method for the icalvalue_as_ical_string_r method because it's returning a char *..
Any suggestions how to solve this issue? I would appreciate any help!
EDIT
Taking a look at the apple doc says the following:
To get a C string from a string object, you are recommended to use UTF8String. This returns a const char * using UTF8 string encoding.
const char *cString = [#"Hello, world" UTF8String];
The C string you receive is owned by a temporary object, and will become invalid when automatic deallocation takes place. If you want to get a permanent C string, you must create a buffer and copy the contents of the const char * returned by the method.
But how to release a char * string properly now if using arc?
I tried to add #autorelease {...} in front of my while-loop but without any effort. Still increasing memory usage...
Careful with the statement "no free method...because it's returning a char*"; that is never something you can just assume.
In the absence of documentation you can look at the source code of the library to see what it does; for example:
http://libical.sourcearchive.com/documentation/0.44-2/icalvalue_8c-source.html
Unfortunately this function can do a lot of different things. There are certainly some cases where calling free() on the returned buffer would be right but maybe that hasn't been ensured in every case.
I think it would be best to request a proper deallocation method from the maintainers of the library. They need to clean up their own mess; the icalvalue_as_ical_string_r() function has at least a dozen cases in a switch that might have different deallocation requirements.
icalvalue_as_ical_string_r returns a char * because it has done a malloc() for your result string. If your pointer is non-NULL, you have to free() it after use.

How do I free() after malloc() when the result of malloc() is returned by the function?

I have the following instance method (adapted from Listing 3-6 of the Event Handling section in the iPhone Application Programming Guide):
- (CGPoint)originOfTouch:(UITouch *)touch
{
CGPoint *touchOriginPoint = (CGPoint *)CFDictionaryGetValue(touchOriginPoints, touch);
if (touchOriginPoint == NULL)
{
touchOriginPoint = (CGPoint *)malloc(sizeof(CGPoint)); // leaks
CFDictionarySetValue(touchOriginPoints, touch, touchOriginPoint);
*touchOriginPoint = [touch locationInView:touch.view];
}
return *touchOriginPoint;
}
Every once in a while my app leaks 16 Bytes as a result of the call to malloc(). I'm not sure how to return touchOriginPoint while free()ing it as well.
If you do not care a minor performance loss, use an NSMutableDictionary and store the point as an NSValue:
NSValue* touchOriginPointValue = [touchOriginPoints objectForKey:touch];
if (touchOriginPointValue == nil) {
touchOriginPointValue = [NSValue valueWithCGPoint:[touch locationInView:touch.view]];
[touchOriginPoints setObject:touchOriginPointValue forKey:touch];
}
return [touchOriginPointValue CGPointValue];
If you must use the CFDictionary approach, you have to find a place to free those malloc-ed memory when the values are not needed. Therefore, you have to pass the values callbacks when creating the dictionary
static void free_malloced_memory (CFAllocatorRef allocator, const void *value) {
free((void*)value);
}
static const CFDictionaryValueCallBacks values_callbacks = {0, NULL, free_malloced_memory, NULL, NULL};
...
touchOriginPoints = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, & values_callbacks);
...
If you must return the malloc'd value from the function, then you have passed the responsibility for freeing the memory to the calling function, or one of its callers.
Since we can't see the calling functions, we can't diagnose any more.
If you are going to be returning an object that is allocated, then either you need to have the caller free() it, or else you need to be using some kind of garbage collection (so it gets freed automatically).
you don't actually return a pointer, the value is copied to a temp value when it is returned, so you aren't really returning the allocation at all, the problem is that you just aren't freeing it either, you add the allocation to the dictionary and just leave it there?
is there like an EndOfTouch function? where you remove the touch from the dictionary? if there is, call free on your allocation there and you should be fine