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);
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'm getting "malloc: * error for object 0xbfffe160: pointer being freed was not allocated" when trying to free memory (in objective-c code) of an object that was allocated inside c function. This C function creates and returns binary data packet that is used as NSData later. Here's my obj-c code part where I'm creating struct variable and passing it by reference to C function:
MyPacket packetRef;
allocAuthentificationCodePacket(&packetRef);
NSData *data = [NSData dataWithBytes:packetRef.bytes length:packetRef.packet->packetSize];
free(&packetRef); // getting error
Everything work fine, except I'm trying to release the memory because the data should be retained by NSData variable. The C functions performs calloc inside itself, so I should somehow to release that memory:
packetRef->bytes = calloc(1, sizeof(*packetRef));
Here's are my structs for storing binary data:
typedef struct {
uint8_t packetType;
uint16_t packetBody;
} MyStruct;
and another struct:
typedef union {
const uint8_t *bytes;
MyStruct *packet;
} MyPacket;
How should I free the memory? The error I'm getting is not crash, it just a message in debug console when running unit tests.
UPDATE. Tried to release "bytes" struct member but getting the same error message:
free(&packetRef.bytes);
UPDATE2. Thanks, the suggested way did worked and malloc error message disappeared from console:
free(packetRef.bytes);
However, getting a warning in Xcode "Passing 'const uint8_t *' (aka 'const unsigned char *') to parameter of type 'void *' discards qualifiers". I'm using Apple LLVM 4.1 compiler. C function resides in separate file and only a header is included because Android guys will have to reuse it.
UPDATE3. Thanks to #simonc and #nos who have pointed out the struct member "bytes" has const. The warning has disappeared after removing const. The initial idea of using const was to protect "bytes" from modification.
This is always wrong. (Hint: It's almost always wrong to put & inside of free().)
MyPacket packetRef;
...
free(&packetRef); // getting error
It doesn't matter what MyPacket is -- it has automatic storage duration, i.e., the compiler automatically allocates storage and frees it when the function exits.
Do not free() something unless it came from malloc() (or calloc(), etc.)
Since packetRef.bytes was allocated with calloc(), you can free() that instead.
MyPacket packetRef;
allocAuthentificationCodePacket(&packetRef);
...
free(packetRef.bytes);
Update
If the function that you call, allocAuthentificationCodePacket, contains the code:
packetRef->bytes = calloc(1, sizeof(*packetRef));
And if the bytes field has type const uint8_t *, then something is wrong.
Perhaps your code is wrong, and you are supposed to call some function to free the packet rather than freeing it yourself.
Perhaps the type of the bytes field is wrong, and should be uint8_t * instead of const uint8_t *.
Perhaps allocAuthentificationCodePacket is wrong.
Who knows? It's not wrong enough to crash, but it is a problem.
Footnote
There are no references in C. &x is "address of x", not "reference to x".
Let's consider the following code:
char *x = malloc(10);
free(x);
When people talk about this code, they will say something like "x is allocated on the heap", but that's not technically correct, x is allocated on the stack and contains the address of 10 bytes on the heap. Likewise, the line free(x) does not actually free x, it frees the memory which x points to.
So when someone tells you, "don't forget to free x", you know they actually mean "don't forget to free the memory which the value contained in x points to". People are sloppy with terminology but computers aren't.
packetRef is a stack variable in your example with packetRef->bytes heap allocated. You should therefore call free(packetRef.bytes)
Since you allocate the memory inside a function - allocAuthentificationCodePacket - you may want to create another function to free the memory
void freePacket(MyPacket* packet)
{
free(packet->bytes);
}
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.
As I understand pointers contain the address of data at another memory location?
When an app is running how is the location of pointers kept track of?
Why bother keeping track of the pointer, why not just directly keep track of address the pointer holds?
Additionally if I have the following code:
NSString *string = #"hello";
string = #"bye";
I am changing the value stored in the pointer named string (is it the pointer that is named string or the NSString object?) to the address of the new string ("bye"), right?
So how would I go about changing directly the object stored at the address held by the pointer?
(Also what is the correct terminology to use where I have used "keep track of"?)
Thanks
Why bother keeping track of the pointer, why not just directly keep
track of address the pointer holds?
Object references in objective C are actually pointers, so each time you use an object (such as NSString), you use a pointer to it - (NSString *)
I am changing the value stored in the pointer named string (is it the
pointer that is named string or the NSString object?) to the address
of the new string ("bye"), right?
Right.
So how would I go about changing directly the object stored at the
address held by the pointer?
In the case of such strings, they are immutable, and you can't change them, in case of other objects, you call their methods, or set their properties.
When an app is running how is the location of pointers kept track of?
Pointers are stored as any other variable; they typically take the same size as an unsigned long, but this is by no means guaranteed, just to give you an idea of how they are implemented. Compilers are free to do a huge variety of optimizations, so the pointers may be stored in memory, they may be stored in registers, or they may exist only as hypothetical entities if they are optimized away.
Consider the following code:
void foo(void) {
char *c;
char buf[100];
for (c=buf; c < buf+100; c++ {
c = '0';
}
}
In this case, the variable c is being used to write an ASCII 0 character to every character in the buf array. c may exist only in a register, because it does not live beyond this function. (There are better ways of writing this code.)
Consider the following code:
struct foo {
char name[10];
struct foo *next;
}
The member next in this case is a pointer to further struct foo objects -- say, a linked list of these things. These pointers must be stored in memory, because they are part of the contract of these objects -- they have to be there. There is no way around these pointers, either -- the objects they point to can be replaced with other objects on the programmer's whim. And, since the number of these objects is determined entirely at runtime, the compiler can't just keep track of the addresses in its symbol tables, as it would for stack-allocated variables.
So how would I go about changing directly the object stored at the address held by the pointer?
This is complicated by your example's use of "foo" strings in the code. These are saved in read-only memory in the process address space, so you cannot modify them. (Surprise!) If you initialize the strings with another method, you can modify the data via the pointer:
char *c = malloc(10);
strcpy(c, "hello");
c[0] = 'H';
printf("c: %s\n", c);
This will overwrite the h with H in the allocated space available via the c pointer. Accessing pointers as if they were arrays is the same re-writing the pointer access like this:
c[0] = 'f';
c+0 = 'f';
And, in fact, array accesses are pretty similar -- the name of the array is the same as a pointer to its first element.
It's a little complicated; the book Expert C Programming covers pointers in astonishing detail and is well worth the money.
Q : So how would I go about changing directly the object stored at the address held by the pointer?
Ans : start using NSMutableString if you want to change the content of memory location pointed by the your string pointer.
NSString is inmutable type ie you can't change the content but you can make the pointer to point somewhere else. "hello" to "bye" in your case.
Out of pure curiosity, I started playing with array's in ways that I have never used before. I tried making a data structure array, and set it equal to another:
typedef struct _test {
float value;
} test;
Simple enough struct, so I tried this:
test struct1[10];
test struct2[20];
struct1 = struct2;
I didn't think this would work, and it didn't even compile. But, this interests me a lot. Is it possible to take an array of 10 and increase the size to 20, while copying the data?
Objective-C
I am actually doing this with Objective-C, so I'd like to hear from the Objective-C people as well. I want to see if it is possible to change the size of struct1 in this file.
#interface Object : NSObject {
test struct1;
}
Remember: This is only out of curiosity, so everything is open to discussion.
Something else that is not exactly pertinent to your question but is interesting nonetheless, is that although arrays cannot be assigned to, structs containing arrays can be assigned to:
struct test
{
float someArray[100];
};
struct test s1 = { /* initialise with some data*/ };
struct test s2 = { /* initialise with some other data */ };
s1 = s2; /* s1's array now contains contents of s2's array */
This also makes it possible to return fixed-length arrays of data from functions (since returning plain arrays is not allowed):
struct test FunctionThatGenerates100Floats(void)
{
struct test result;
for (int i = 0; i < 100; i++)
result.someArray[i] = randomfloat();
return result;
}
As others have said, arrays allocated like that are static, and can not be resized. You have to use pointers (allocating the array with malloc or calloc) to have a resizable array, and then you can use realloc. You must use free to get rid of it (else you'll leak memory). In C99, your array size can be calculated at runtime when its allocated (in C89, its size had to be calculated at compile time), but can't be changed after allocation. In C++, you should use std::vector. I suspect Objective-C has something like C++'s vector.
But if you want to copy data between one array and another in C, use memcpy:
/* void *memcpy(void *dest, const void *src, size_t n)
note that the arrays must not overlap; use memmove if they do */
memcpy(&struct1, &struct2, sizeof(struct1));
That'll only copy the first ten elements, of course, since struct1 is only ten elements long. You could copy the last ten (for example) by changing &struct2 to struct2+10 or &(struct2[10]). In C, of course, not running off the end of the array is your responsibility: memcpy does not check.
You can also you the obvious for loop, but memcpy will often be faster (and should never be slower). This is because the compiler can take advantage of every trick it knows (e.g., it may know how to copy your data 16 bytes at a time, even if each element is only 1 byte wide)
You can't do this in C with static arrays, but you can do it with dynamically allocated arrays. E.g.,
float *struct1, *struct2, *struct3;
if(!(struct1 = malloc(10 * sizeof(float))) {
// there was an error, handle it here
}
if(!(struct2 = realloc(struct1, 20 * sizeof(float))) {
// there was an error, handle it here
// struct1 will still be valid
}
if(!(struct3 = reallocf(struct2, 40 * sizeof(float))) {
// there was an error, handle it here
// struct2 has been free'd
}
In C, I believe that's a good place to use the realloc function. However, it will only work with dynamically allocated arrays. There's no way to change the memory allocated to struct1 by the declaration test struct1[10];.
In C arrays are constants, you can't change their value (that is, their address) at all, and you can't resize them.
Clearly if you declare your array with a fixed size, test struct1[10] then it cannot be resized. What you need to do is to declare it as a pointer:
test *struct1;
Then you must use malloc to allocate the array and can use realloc to resize it whilst preserving the contents of the original array.
struct1 = malloc(10*sizeof(*struct1));
//initialize struct1 ...
test *struct2 = realloc(struct1, 20*sizeof(*struct1));
If you're using Objective C, you know you can just use NSMutableArray, which automatically does the realloc trick to reallocate itself to store however many objects you put in it, up the limit of your memory.
But you're trying to do this with struct? What would that even mean? Suppose you increase the amount of memory available to struct1 in Object. It's still a struct with one member, and doesn't do anything more.
Is the idea to make Object be able to contain an expanded struct?
typedef struct _test2 {
float value;
NSObject *reference;
} test2;
But then you still can't access reference normally, because it's not a known part of Object.
Object *object2;
...
NSLog(#"%#", object2.struct1.reference); // does not compile
If you knew you had one of your modified objects, you could do
Object *object2;
...
NSLog(#"%#", ((test2)(object2.struct1)).reference);
And also you could still presumably pass object2 to anything that expects an Object. It only has any chance of working if struct1 is the last member of Object, and don't mess with subclassing Object either.
Some variety of realloc trick might then work, but I don't think realloc in particular, because that's intended to be used on objects that are allocated with malloc, and the details of what C function is used to allocate objects in not exposed in Objective C, so you shouldn't assume it's malloc. If you override alloc then you might be able to make sure malloc is used.
Also you have to watch out for the fact that it's common in Objective C for more than one pointer to an object to exist. realloc might move an object, which won't be semantically correct unless you correct all the pointers.