In programming there is a general rule introduced by Kernighan & Ritchie saying that you have call a "free" for all space allocated by a "malloc".
So the following code is correct:
- (UIImage*) convertImage:(UIImage*)sourceImage {
unsigned char *rawData = malloc(requiredSpace);
...
...
free(rawData);
return imageRef;
}
However you also have encapsulation within a function. So after the return from the function, the memory will be automatically freed. So theoretically the free is not absolutely required in the above example. Is this correct?
Absolutely no.
The free is necessary since the memory will be freed only for statically allocated variables. If you use malloc (as well as calloc or realloc) you are dynamically allocating memory that will not be freed except if you explicitly call free.
For example:
-(void)method {
char a[10];
char *b = (char*) malloc(10*sizeof(char));
}
a will be destroyed at the end of the scope (at least, will be marked as free memory, so that you cannot rely anymore on its content), while b remains in memory until the end of the program. If you lose the pointer to that memory address (maybe assigning another value to b or simply ending the function without returning b), you will not be able to free the memory anymore, and this will bring to a memory leak.
Related
This question already has answers here:
What and where are the stack and heap?
(31 answers)
Closed 8 years ago.
Primitive data types such as char, bool and int have some memory. Suppose char, which has 1 byte of memory. When we use a char variable in our code, then the variable must require 1 byte of memory. Why don't we allocate memory in this case. And as we never allocate memory for it, how does it use the memory ,i.e. Is the CPU allocate memory for it in this case.Also I read somewhere that the primitive data types are put on stack and removed when the work is done for it. What kind of stack? How does the stack comes into picture in this case?
When we create an NSString * variable, we don't allocate the memory for this either.
We only allocate memory when alloc is called, either directly by us or inside a method we call.
An NSString object exists on the heap in memory we've allocated, but the NSString * variable (which is, a pointer to an NSString object) exists in memory on the stack which we do not allocate.
For example, given these two variables:
NSString *stringOne;
NSString *stringTwo;
So far, neither has been allocated any memory on the heap, although they do exist in memory in the exact same way a char, BOOL, or int exists in memory.
NSString *stringOne = [[NSString alloc] initWithString:#"Hello world"];
NSString *stringTwo = stringOne;
Now what has happened? We allocated some memory on the heap for an NSString object. We then initialized this memory to represent the string "Hello world" and then returned a pointer to this object and assigned it to stringOne.
Next, we simply copied that pointer over into the stack memory we're using for stringTwo. We didn't allocate any extra memory on the heap. We simply made our two string variable point to the same allocated memory on the heap.
The question and answer jsd linked in the comments has more explanation on stack and heap memory which will answer some of your questions.
It's also worth noting that a lot of other programming languages such as C++ allow objects to be created on the stack, in which case we don't allocate them, as we would with heap objects. They do exist in memory, just more similarly to primitive data types.
At the risk of being over simplistic, there are three classes of memory for data: 1) static, 2) stack 3) heap.
They are allocated in different ways.
if you have
static char something ;
defined in a function or
char something ;
outside of a function, that data is defined by the linker using instructions from the compiler and allocated by the program loaders.
Nearly every processor in existence uses a stack to support nested data (e.g., function calls). The stack is a block of memory that exists for every process (and for every processor mode). There is a a hardware register called the Stack Pointer that identifies the current position of the stack. Usually the SP starts at the high end of the stack and works downward. To allocate memory on the stack, the program subtracts the number of bytes required from the stack pointer. To deallocate, it adds to the stack pointer. The allocations and deallocations always take place at the same end.
There are then two operations on the stack. PUSH means put something on the stack. POP removes it. Most processors have instructions to PUSH and POP
If you have
char something
defined within a function, that memory is allocated by the program as directed by the compiler by doing something like this to adjust the stack pointer (I'm leaving out a frame pointer for now)
SUB BYTESNEEDED, SP
upon entering the function and freed by doing
ADD BYTESNEEDED, SP
before leaving the function. During the execution of the function, the local variables are at offsets from the stack pointer.
This usually done by using a second register, usually called a frame pointer. A function usually does something like this at the start
PUSH FP ; Save the old Frame Point
MOV SP FP ; Save the stack pointer
SUB BYTESNEEDED, SP
at the end the function does something like
MOV FP, SP ; Free all the stack allocated by the function
POP FP ; Restore the old stack pointer
The reason for using two registers is that it is possible to dynamically allocate data from the stack.
THere is a common function (although I believe it is not a standard C function) called alloca that is an alternative to malloc that allocates from the stack
void dosomething (int amount)
{
char *data = alloca (amount) ;
}
With alloca, the data is automatically freed when the function returns and resets the stack.
That is a long winded answer to your question. Yes, when declare a char, there has to be an allocation for it. However, this allocation is done behind the scenes without effort on your part.
I am pointing to the address of a 2D array, and I am confused as to how to dereference the pointer to free up the memory again. (I don't use "->" or "*". Is that wrong?)
My code:
double array[12][12];
//filled with numbers
double *arrayPtr; //pointer
arrayPtr = &array[0][0]; //pointing to address
multiply(arrayPtr, arrayPtr); //this works fine
//Do I need to do anything further to make sure my memory management is correct? And if so, why?
In this case, the answer is no -- since you simply defined array (didn't use something like malloc to allocate it) you don't have to do anything to free it either. If it was local (defined inside a function) it'll be freed automatically when you exit the function. If you defined it outside any function, it's a global, so it'll exist the entire time the program runs. Either way, you don't have to d any explicit memory management.
double array[12][12];
You're declaring array on the stack. It's not dynamically allocated with the heap, so you don't "free up the memory".
double *arrayPtr; //pointer
arrayPtr = &array[0][0]; //pointing to address
If you want to point to the first element, this would suffice:
double* arrayPtr = array;
First, there a quite different between C and C++
In C to use memory management you shall use malloc/calloc/realloc and free. In c++ you will use new and delete.
In your code.
double array[12][12];
This is imply to allocate memory in stack. So the memory will be allocated to the scope of this program section so that it will be green when the scope of this variable end.
If you will to use free you will need
double **array;
array = (double **) malloc(sizeof(double*));
*array = (double*) malloc (24 * sizeof(double));
free (*array);
free (array);
According to the documentation for NSString's method -UTF8String:
The returned C string is automatically
freed just as a returned object would
be released; you should copy the C
string if it needs to store it outside
of the autorelease context in which
the C string is created.
So under retain/release memory management, the following method:
- (const char*) giveMeACString
{
NSString* string = #"I'm a string!";
return [string UTF8String];
}
is fine, so long as the calling method treats the returned const char* as it would an autoreleased object.
However, under garbage collection there isn't an autorelease context, as far as I'm aware. And C types aren't garbage collected, so it doesn't look like the GC will treat the returned pointer as it would a returned object.
What is its lifespan tied to? Is it still freed at a point in the thread's runloop that is reliably `later on', or does it behave differently under GC than under non-GC?
I think the memory is allocated from garbage collected memory and the return type is __strong const char*. This means that it will be collected in the normal way when it is not reachable from the root set of pointers.
That basically means you need to store it in a pointer variable that is marked as __strong or it will be collected at some point.
I'd speculate that an immutable string maintains a reference to the UTF8 version of itself, so it only has to calculate it once and therefore the UTF8 string probably won't go away until the NSString does which is why you don't have to worry about it disappearing normally.
Since you did not explicitly allocate those spaces, you do not need to worry about deallocation.
I'm a first time Objective C programmer. I've been reading other people's code and I often see static strings created but never released. Take this for example:
- (UITableViewCell*)tableView:(UITableView*)tableView
cellForRowAtIndexPath:(NSIndexPath*)indexPath
{
static NSSSTring* foo = #"foo";
// [code to return a cell for the table]
}
To my understanding, space for 3 characters in the heap has been allocated to store the string "foo". When the program terminates, those 3 characters are never reclaimed because the author never releases them. Isn't there a memory leak here? Why or why not?
Actually, constant strings like #"foo" are treated specially by the compiler. In particular, they are not heap allocated, and they do not participate in reference counting, i.e., they are never actually released; their memory is part of your program's image, just like the content of, say, "foo". However, this should be treated as implementation detail of this particular kind of NSString subclass. Follow the usual rules for reference retention/release.
I am slightly bemused by the following property points of class MKMultiPoint in MapKit:
#property (nonatomic, readonly) MKMapPoint *points
It returns an array of struct. One can know the number of elements in the array with the pointCount property.
With my limited knowledge of C, I always thought C-arrays could only be "sort of returned" if passed by reference to a function because the caller is responsible for allocating the memory and then releasing it.
If I were to write a similar property, who would allocate the memory for the array (presumably the callee) and more importantly who would free it (presumably the caller)? That sounds a bit risky to me. Besides, the documentation for the property above doesn't say anything about having to free memory.
What am I missing?
(The sample code is in C).
The good practice is to allocate and free a resource at the same level. There are two ways to define a function that returns an array of things:
// `points` are allocated and freed by the caller.
void MakePoints (MKMapPoint *points, size_t number_of_points);
// usage:
size_t count = 10;
MKMapPoint *points = malloc (sizeof (MKMapPoint) * 10);
MakePoints (points, count);
// Use points
free (points);
// or simply
MKMapPoint points[10];
MakePoints (points, 10);
// Use points
The second way is to let the library function manage the memory:
MKMapPoint *MakePoints (size_t number_of_points);
void FreePoints (MKMapPoint *points);
// Usage:
MKMapPoint *points = MakePoints (10);
// Use points
// The library need not necessarily call free() on points,
// it might reuse it in further calls to MakePoints().
FreePoints (points);
The receiver, in most cases, would handle allocating the memory. Who frees it depends on how you determine ownership. Is the memory allocated by the receiver no longer needed once it's returned? If so, you should probably note in your documentation that the caller needs to free the returned array. If the receiver can reuse the returned memory, leave deallocation to it.
If you wanted to leave it up to the callee to handle memory allocation, you probably wouldn't use a property and instead opt for a message and property like so:
- (NSUInteger) mapPointCount;
- (void) getMapPoints:(MKMapPoint *)pointsOut;
where the sender should provide an existing buffer to store obj.mapPointCount number of MKMapPoints in. Then, you've placed the responsibility for allocation/deallocation on the caller.
If you don't want to go that route, and since the memory in question can't be retained/released/autoreleased by the receiver, I would leave it up to the caller to release it. If you want to make it somewhat clear that the memory is not to be freed, return it with the type const MKMapPoint * and note it in some form of documentation (which should hopefully make it clear that the memory is not owned by whoever accesses the data).
Alternatively, store it in an NSData or something and make it clear that once the next autorelease pool is drained, the pointer is invalid. However, that's a little less friendly, and possibly not safe with garbage collection. Probably wrong about that last bit, but I don't know enough to say, so I'll prefer caution for now.