Related
I'm a bit weak when it comes to memory allocation and pointers.
So, I want to understand why do I have to allocate memory to pointers in functions as follow:
char *cstring(char c, int n)
{
int i = 0;
char * res;
res = malloc ((n+1)*sizeof(char));
while (i<n)
{
res[i]=c;
i++;
}
res[i] ='\0';
return res;
}
and why is the following not valid?
char *cstring(char c, int n)
{
int i = 0;
char * res;
while (i<n)
{
res[i]=c;
i++;
}
res[i] ='\0';
return res;
}
I understand that I should allocate memory (generally) to pointers so that they have defined memory.
However, I want to mainly understand how is it related to the concept of stack and heap memories!
Thanks in advance!
Pointers need to point to a valid memory location before they can be dereferenced.
In your first example, res is made to point at a block of allocated memory which can subsequently be written to and read from.
In your second example, res remains uninitialized when you attempt to dereference it. This causes undefined behavior. The most likely outcome in this case is that whatever garbage value it happens to contain will not be a valid memory address, so when you attempt to dereference that invalid address your program will crash.
If you declare a variable like that,
int A = 5;
then that means the variable will be on the stack. When functions are called, their local variables are pushed to the stack. The main function is also an example of that. So you don't have to allocate memory manually, your compiler will do this for you in the background before it calls your main function. And that also means if you examine the stack during the execution of the function you can see the value 5.
With this,
int A = 5;
int *PtrToA = &A;
The pointer will be on the stack again. But this time, the value on the stack just shows the memory address of the actual integer value we want. It points to the address of the memory block that holds the value 5. Since A is held in the stack here, pointer will show a memory address on the stack.
Like the case in your question you can allocate memory dynamically. But you have to initialize it before you read it. Because when you request to allocate the memory, your operating system searches for a valid memory field in your programs heap and reserves that for you. Than it gives you back its adddress and gives you the read write permissions so you can use it. But the values in it won't contain what you want. When compiler allocates on stack, the initial values will be unset again. If you do this,
char *res;
res[1] = 3;
variable res will be on the stack and it will contain some random value. So accessing it is just like that,
(rand())[1] = 3;
You can get an access violation error because you may not have permission to write to that memory location.
An important note; after your function call returns, values of local variables on the stack are no more valid. So be careful with that. Do not dereference them after the function call ends.
In conclusion; if you want to use a pointer, be sure it points to a valid memory location. You can allocate it yourself or make it point another memory address.
The second version of your code declares a pointer, but does not initialize it to point to a valid memory address.
Then, the code dereferences that pointer -- during the loop. So, your code would access uninitialized memory in this case. Remember, array indexing is just syntactic sugar for dereferencing -- so your code accesses memory its not supposed to.
The first version of your code initializes the pointer to actually point to something, and hence when you dereference it during the loop, it works.
Of course, in either case, you return the pointer from the function -- its just that in the first version it points to something valid, whereas in the second version it points anywhere.
The moral here is to always initialize your variables. Not doing so could result in undefined behavior in your code (even if it appears to work sometimes). The general advice here is to always compile your code using at least some compilation flags. For example in gcc/clang, consider -Wall -Werror -Wextra. Such options often pick up on simple cases of not initializing variables.
Also, valgrind is a brilliant tool for memory profiling. It can easily detect uses of uninitialized memory at runtime, and also memory leaks.
Simple: because you do not have any allocated memory for the data you wite. In your example you define pointer, you do not initialize it so it will reference random (or rather not possible to predict) place in the memory, then you try to write to this random memory location.
You have 2 Undefined Behaviours here in 5 lines example. Your pointer is not initialized, and you did not allocate any valid memory this pointer to reference.
EDIT:
VALID
char *cstring(char c, int n)
{
char * res;
res = malloc ((n+1)*sizeof(char));
char *cstring(char c, int n)
{
char * res;
static char buff[somesize];
res = buff;
char buff[somesize];
char *cstring(char c, int n)
{
char * res;
res = buff;
INVALID
char *cstring(char c, int n)
{
char * res;
char buff[somesize];
res = buff;
Is there a possible way to make static array of structs points to NULL since I can't delete arrays and I want to clean the memory?
Suppose we have the following code:
struct_x defaultStructX[6];
struct_x requiredStructX [6];
gettingDefaultX(defaultStructX, 6);
for (uint8_t i = 0; i <6; i++)
{
setStructX(requiredStructX[i].index, requiredStructX[i].icirate, requiredStructX[i].icis, requiredStructX[i].iei);
//error handle case
if (status == STATUS_SUCCESS)
{
writeResponse.writeStatus = status_ok; /*This is another struct not important at this point*/
} else
{
errorHandleQciFlowMeter(defaultStructX, 6);
writeResponse.writeStatus = status_nok;
break;
}
}
/*here I want to write code line to clean the defaultStructX from memory. Is it possible? I have tried *defaultStructX[i]= NULL and ##((void*)defaultQciFlowMeter) = NULL; ## and many other methods but it didn't work*/
Is there a possible way to make static array of stucts points to NULL since I can't delete arrays and I want to clean the memory?
No. Arrays are not pointers, nor are the elements of your particular arrays pointers, either. Pointer values cannot be assigned to either the arrays themselves or to the elements, and in particular, NULL cannot be assigned to them.
You can overwrite the memory occupied by the array with, say,
memset(defaultStructX, 0, sizeof(defaultStructX));
That will replace the data previously stored within,* which might be useful if those data were sensitive. The application would then need to assign new, valid values to the array elements before using them again.
Any way around, however, you cannot free the memory of an object with static storage duration, which is any object declared at file scope, outside all functions, or with the static qualifier inside a function. The entire point of static storage duration is for objects' lifetimes to be the entire duration of the program's run. If you want to be able to release the memory then you should allocate space for your arrays dynamically, or, if it works for your particular application, automatically (as a local variable of a well-chosen function).
* In principle. As #chux noted in comments, it may be the case that the compiler chooses to optimize out such an overwrite, which it might do if it could determine that the zeroed out data were never read. If this is a concern, then the best mitigation would probably be to declare the arrays volatile.
struct_x defaultStructX[6];
struct_x requiredStructX [6];
With the above statements, you have reserved memory for the two arrays of structs. This memory will remain allocated to you during the entire lifetime of your program and cannot be de-allocated until your program exits.
However, what you want to store in this memory is completely under your control. What is your definition of 'cleaning from memory'?
Do you haves some sensitive data that you want to erase from memory? You can always memset them to zero (or any other value) with:
memset(defaultStructX, 0x00, sizeof(defaultStructX));
Do you want to physically de-allocate the memory? If you want to have control over allocation and deallocation of chunks of memory, you should do so with malloc and free.
EDIT: Apparently the memset() solution can be derailed by compiler optimizations.
Here is a useful description of this issue from the SEI CERT C page.
You cannot manually deallocate anything that wasn’t allocated with malloc, calloc, or realloc. If you declared your arrays at file scope (outside of any function) or with the static keyword, then their memory won’t be released until the program terminates. Otherwise, their memory will be released when the function in which they were declared exits.
You can overwrite elements not currently in use with zeros or some other “not a value” value, but you cannot free the memory they occupy.
Arrays are not pointers. Expressions of array type are converted to pointers as necessary, but the array object itself is not a pointer.
Is there a possible way to make static array of structs points to NULL since I can't delete arrays and I want to clean the memory?
No. Arrays do not point. The array could be cleared.
I want to write code line to clean the defaultStructX from memory.
Simply assigned zeros to it.
memset() can get optimized out if the compiler sees the data was not subsequently read.
Alternative: use a loop with a pointer to volatile data to avoid loop from being optimized out.
volatile unsigned char *vp = defaultStructX;
for (size_t i = 0; i<sizeof defaultStructX; i++ {
vp[i] = 0;
}
Hmm... On one hand I love the detailed answer offered by John Bollinger and I believe he gave the correct answer for your use case... however...
There is a way to make the statically allocated array appear to point to NULL.
Obviously you can't assign NULL to an array. However, you can make a statically allocated "Array" seem to point to NULL by hiding it behind a pointer.
It might look like this:
#define STRUCT_X_ARRAY_LENGTH 6
struct_x defaultStructX___[STRUCT_X_ARRAY_LENGTH];
struct_x requiredStructX___[STRUCT_X_ARRAY_LENGTH];
struct_x * defaultStructX = defaultStructX___;
struct_x * requiredStructX = requiredStructX___;
gettingDefaultX(defaultStructX, STRUCT_X_ARRAY_LENGTH);
Now you could set the (no longer) "Array" to NULL using:
defaultStructX = NULL;
requiredStructX = NULL;
You could also reset the state (zero out the memory and reassign the correct memory address) using:
defaultStructX = defaultStructX___;
requiredStructX = requiredStructX___;
memset(defaultStructX___, 0 , sizeof(defaultStructX___));
memset(defaultStructX___, 0 , sizeof(requiredStructX___));
Not that this fits your use case, but it's a good enough technique that others might want to know about it.
So i want to return an array of a size n (variable) which my function has as input. I know that in order to return arrays in C I have to define them static, but the problem is that n is a variable and thus I get an error. I thought of actually using malloc/calloc but then I won't be able to free them after the function returns the array. Please take note that I'm not allowed to change anything on main(). Are there any other alternatives which I could use? Thanks in advance.
float *Arr( int *a , int n ){
static float b[ n ];
return b
}
Got to point out that the function will only be called Once,I saw the solution you posted but i noticed you aren't freeing the allocated memory,is it not of much importance when the malloc is called inside a function?
The important thing to notice here is that this syntax:
float arr[n];
Allocates an array on the stack of the current function. In other words, that array is a local variable. Any local variable becomes invalid after the function returns, and therefore returning the array directly is undefined behavior. It will most likely cause a crash when trying to access the array from outside the function, if not anything worse.
In addition to that, declaring a variable-length array as static is invalid in any case.
If you want to write a function which creates and returns any kind of array (dynamically sized or not), the only option you have is to use dynamic allocation through malloc() and then return a pointer to the array (technically there's also alloca() to make dynamic stack allocations, but I would avoid it as it can easily break your program if the allocation is too large).
Here's an example of correct code:
float *create_array(size_t n_elements){
float *arr = malloc(sizeof(float) * n_elements);
if (arr == NULL) {
// Memory could not be allocated, handle the error appropriately.
}
return arr;
}
In this case, malloc() is reserving memory outside of the local stack of the function, in the heap. The result is a pointer that can be freely returned and passed around without any problem, since that area of memory keeps being valid after the function returns (until it is released). When you're done working with the data, you can release the allocated memory by calling free():
float *arr = create_array(100);
// ...
free(arr);
If you don't have a way to release the memory through free() after using malloc(), that's a problem in the long run, but in general, it is not a strict requirement: if your array is always needed, from its creation until the exit of the program, then there's no need to explicitly free() it, since memory is automatically released when the program terminates.
If your function needs to be called more than once or needs to create significantly sized arrays that are only useful in part of the program and should therefore be discarded when no longer in use, then I'm afraid there's no good way of doing it. You should use free() in that case.
To answer your question precisely:
Please take note that I'm not allowed to change anything on main(). Are there any other alternatives which I could use?
No, there are no other better alternatives. The only correct approach here is to dynamically allocate the array through malloc(). The fact that you cannot free it afterwards is a different kind of problem.
So i want to return an array of a size n(variable) which my function
has as input,
You can't, because C functions cannot return arrays at all. They can, and some do, return pointers, however, as your function is declared to do. Such a pointer may point to an element of an array.
i know that in order to return arrays in c i have to
define them static,
As long as I am being pedantic, the problem is to do with the lifetime of the object to which the returned pointer points. If it is an element of an automatically-allocated array, then it, along with the rest of the array, ceases to exist when the function returns. The caller must not try to dereference such a pointer.
The two other alternatives are
static allocation, which you get by declaring the variable static or by declaring it at file scope, and
dynamic allocation, which you get by reserving memory via malloc(), calloc(), or a related function.
Statically allocated objects exist for the entire lifetime of the program, and dynamically allocated ones exist until deallocated.
but problem is that n is a variable and thus i get
an error.
Yes, because variable-length arrays must be automatically allocated. Static objects exist for the whole run of the program, so the compiler needs to reserve space for them at compile time.
I thought of actually using malloc/calloc but then i won't be
able to free them after the function returns the array.
That's correct, but dynamic allocation is still probably the best solution. It is not unreasonable for a called function to return a pointer to an allocated object, thus putting the responsibility on its caller to free that object. Ordinarily, that would be a well-documented characteristic of the function, so that its callers know that such responsibility comes with calling the function.
Moreover, although it's a bit untidy, if your function is to be called only once then it may be acceptable to just allow the program to terminate without freeing the array. The host operating system can generally be relied upon to clean up the mess.
Please take
note that im not allowed to change anything on main(),are there any
other alternatives which i could use?
If you have or can impose a bound on the maximum value of n then you can declare a static array of that maximum size or longer, and return a pointer to that. The caller is receiving a pointer, remember, not an array, so it can't tell how long the pointed-to array actually is. All it knows is that the function promises n accessible elements.
Note well that there is a crucial difference between the dynamic allocation and static allocation alternatives: in the latter case, the function returns a pointer to the same array on every call. This is not inherently wrong, but it can be problematic. If implemented, it is a characteristic of the function that should be both intentional and well-documented.
If want an array of n floats where n is dynamic, you can either create a
variadic-length array (VLA):
void some_function(...)
{
//...
float b[ n ]; //allocate b on the stack
//...
}
in which case there would be no function call for the allocation, or you can allocate it dynamically, e.g., with malloc or calloc, and then free it after you're done with it.
float *b = malloc(sizeof(*b)*n);
A dynamic (malloc/calloc) allocation may be wrapped in a function that returns a pointer to the allocated memory (the wrapper may do some initializations on the allocated memory after the memory has been successfully allocated). A VLA allocation may not, because a VLA ends its lifetime at the end of its nearest enclosing block (C11 Standard - 6.2.4 Storage durations of objects(p7)).
If you do end up wrapping a malloc/calloc call in a "constructor" function like your float *Arr(void), then you obviously should not free the to-be-returned allocated memory inside Arr–Arr's caller would be responsible for freeing the result (unless it passed the responsibility over to some other part of the program):
float *Arr( int n, ...
/*some params to maybe initialize the array with ?*/ )
{
float *r; if (!(r=malloc(sizeof(*r)*n)) return NULL;
//...
//do some initializations on r
//...
return r; //the caller should free it
}
you could use malloc to reserve memory for your n sized array
Like this:
#include <stdlib.h>
#include <stdio.h>
float * arr(int * a, int n ) {
float *fp = malloc ( (size_t) sizeof(float)*n);
if (!fp) printf("Oh no! Run out of memory\n");
return fp;
}
int main () {
int i;
float * fpp = arr(&i,200);
printf("the float array is located at %p in memory\n", fpp);
return(0);
}
It seems like what you want to do is:
have a function that provides (space for) an array with a variable number of elements,
that the caller is not responsible for freeing,
that there only needs to be one instance of at a time.
In this case, instead of attempting to define a static array, you can use a static pointer to manage memory allocated and freed with realloc as needed to adjust the size, as shown in the code below. This will leave one instance in existence at all times after the first call, but so would a static array.
This might not be a good design (it depends on circumstances not stated in the question), but it seems to match what was requested.
#include <stdio.h>
#include <stdlib.h>
float *Arr(int *a , int n)
{
// Keep a static pointer to memory, with no memory allocated initially.
static float *b = NULL;
/* When we want n elements, use realloc to release the old memory, if any,
and allocate new memory.
*/
float *t = realloc(b, n * sizeof *t);
// Fail if the memory allocation failed.
if (!t)
{
fprintf(stderr, "Error, failed to allocate memory in Arr.\n");
exit(EXIT_FAILURE);
}
// Return the new memory.
return b;
}
I am working with my first straight C project, and it has been a while since I worked on C++ for that matter. So the whole memory management is a bit fuzzy.
I have a function that I created that will validate some input. In the simple sample below, it just ignores spaces:
int validate_input(const char *input_line, char** out_value){
int ret_val = 0; /*false*/
int length = strlen(input_line);
out_value =(char*) malloc(sizeof(char) * length + 1);
if (0 != length){
int number_found = 0;
for (int x = 0; x < length; x++){
if (input_line[x] != ' '){ /*ignore space*/
/*get the character*/
out_value[number_found] = input_line[x];
number_found++; /*increment counter*/
}
}
out_value[number_found + 1] = '\0';
ret_val = 1;
}
return ret_val;
}
Instead of allocating memory inside the function for out_value, should I do it before I call the function and always expect the caller to allocate memory before passing into the function? As a rule of thumb, should any memory allocated inside of a function be always freed before the function returns?
I follow two very simple rules which make my life easier.
1/ Allocate memory when you need it, as soon as you know what you need. This will allow you to capture out-of-memory errors before doing too much work.
2/ Every allocated block of memory has a responsibility property. It should be clear when responsibility passes through function interfaces, at which point responsibility for freeing that memory passes with the memory. This will guarantee that someone has a clearly specified requirement to free that memory.
In your particular case, you need to pass in a double char pointer if you want the value given back to the caller:
int validate_input (const char *input_line, char **out_value_ptr) {
: :
*out_value_ptr =(char*) malloc(length + 1); // sizeof(char) is always 1
: :
(*out_value_ptr)[number_found] = input_line[x];
: :
As long as you clearly state what's expected by the function, you could either allocate the memory in the caller or the function itself. I would prefer outside of the function since you know the size required.
But keep in mind you can allow for both options. In other words, if the function is passed a char** that points to NULL, have it allocate the memory. Otherwise it can assume the caller has done so:
if (*out_value_ptr == NULL)
*out_value_ptr =(char*) malloc(length + 1);
You should free that memory before the function returns in your above example. As a rule of thumb you free/delete allocated memory before the scope that the variable was defined in ends. In your case the scope is your function so you need to free it before your function ends. Failure to do this will result in leaked memory.
As for your other question I think it should be allocated going in to the function since we want to be able to use it outside of the function. You allocate some memory, you call your function, and then you free your memory. If you try and mix it up where allocation is done in the function, and freeing is done outside it gets confusing.
The idea of whether the function/module/object that allocates memory should free it is somewhat of a design decision. In your example, I (personal opinion here) think it is valid for the function to allocate it and leave it up to the caller to free. It makes it more usable.
If you do this, you need to declare the output parameter differently (either as a reference in C++ style or as char** in C style. As defined, the pointer will exist only locally and will be leaked.
A typical practice is to allocate memory outside for out_value and pass in the length of the block in octets to the function with the pointer. This allows the user to decide how they want to allocate that memory.
One example of this pattern is the recv function used in sockets:
ssize_t recv(int socket, void *buffer, size_t length, int flags);
Here are some guidelines for allocating memory:
Allocate only if necessary.
Huge objects should be dynamically
allocated. Most implementations
don't have enough local storage
(stack, global / program memory).
Set up ownership rules for the
allocated object. Owner should be
responsible for deleting.
Guidelines for deallocating memory:
Delete if allocated, don't delete
objects or variables that were not
dynamically allocated.
Delete when not in use any more.
See your object ownership rules.
Delete before program exits.
In this example you should be neither freeing or allocating memory for out_value. It is typed as a char*. Hence you cannot "return" the new memory to the caller of the function. In order to do that you need to take in a char**
In this particular scenario the buffer length is unknown before the caller makes the call. Additionally making the same call twice will produce different values since you are processing user input. So you can't take the approach of call once get the length and call the second time with the allocated buffer. Hence the best approach is for the function to allocate the memory and pass the responsibility of freeing onto the caller.
First, this code example you give is not ANSI C. It looks more like C++. There is not "<<" operator in C that works as an output stream to something called "cout."
The next issue is that if you do not free() within this function, you will leak memory. You passed in a char * but once you assign that value to the return value of malloc() (avoid casting the return value of malloc() in the C programming language) the variable no longer points to whatever memory address you passed in to the function. If you want to achieve that functionality, pass a pointer to a char pointer char **, you can think of this as passing the pointer by reference in C++ (if you want to use that sort of language in C, which I wouldn't).
Next, as to whether you should allocate/free before or after a function call depends on the role of the function. You might have a function whose job it is to allocate and initialize some data and then return it to the caller, in which case it should malloc() and the caller should free(). However, if you are just doing some processing with a couple of buffers like, you may tend to prefer the caller to allocate and deallocate. But for your case, since your "validate_input" function looks to be doing nothing more than copying a string without the space, you could just malloc() in the function and leave it to the caller. Although, since in this function, you simply allocate the same size as the whole input string, it almost seems as if you might as well have the caller to all of it. It all really depends on your usage.
Just make sure you do not lose pointers as you are doing in this example
Some rough guidelines to consider:
Prefer letting the caller allocate the memory. This lets it control how/where that memory is allocated. Calling malloc() directly in your code means your function is dictating a memory policy.
If there's no way to tell how much memory may be needed in advance, your function may need to handle the allocation.
In cases where your function does need to allocate, consider letting the caller pass in an allocator callback that it uses instead of calling malloc directly. This lets your function allocate when it needs and as much as it needs, but lets the caller control how and where that memory is allocated.
Someone here recently pointed out to me in a piece of code of mine I am using
char* name = malloc(256*sizeof(char));
// more code
free(name);
I was under the impression that this way of setting up an array was identical to using
char name[256];
and that both ways would require the use of free(). Am I wrong and if so could someone please explain in low level terms what the difference is?
In the first code, the memory is dynamically allocated on the heap. That memory needs to be freed with free(). Its lifetime is arbitrary: it can cross function boundaries, etc.
In the second code, the 256 bytes are allocated on the stack, and are automatically reclaimed when the function returns (or at program termination if it is outside all functions). So you don't have to (and cannot) call free() on it. It can't leak, but it also won't live beyond the end of the function.
Choose between the two based on the requirements for the memory.
Addendum (Pax):
If I may add to this, Ned, most implementations will typically provide more heap than stack (at least by default). This won't typically matter for 256 bytes unless you're already running out of stack or doing heavily recursive stuff.
Also, sizeof(char) is always 1 according to the standard so you don't need that superfluous multiply. Even though the compiler will probably optimize it away, it makes the code ugly IMNSHO.
End addendum (Pax).
and that both ways would require the use of free().
No, only the first needs the use of a free. The second is allocated on the stack. That makes it incredibly fast to allocate. Look here:
void doit() {
/* ... */
/* SP += 10 * sizeof(int) */
int a[10];
/* ... (using a) */
} /* SP -= 10 */
When you create it, the compiler at compile time knows its size and will allocate the right size at the stack for it. The stack is a large chunk of continuous memory located somewhere. Putting something at the stack will just increment (or decrement depending on your platform) the stackpointer. Going out of scope will do the reverse, and your array is freed. That will happen automatically. Therefor variables created that way have automatic storage duration.
Using malloc is different. It will order some arbitrary large memory chunk (from a place called freestore). The runtime will have to lookup a reasonably large block of memory. The size can be determined at runtime, so the compiler generally cannot optimize it at compile time. Because the pointer can go out of scope, or be copied around, there is no inherent coupling between the memory allocated, and the pointer to which the memory address is assigned, so the memory is still allocated even if you have left the function long ago. You have to call free passing it the address you got from malloc manually if the time has come to do so.
Some "recent" form of C, called C99, allows you to give arrays an runtime size. I.e you are allowed to do:
void doit(int n) {
int a[n]; // allocate n * sizeof(int) size on the stack */
}
But that feature should better be avoided if you don't have a reason to use it. One reason is that it's not failsafe: If no memory is available anymore, anything can happen. Another is that C99 is not very portable among compilers.
There is a third possibility here, which is that the array can be declared external to a function, but statically, eg,
// file foo.c
char name[256];
int foo() {
// do something here.
}
I was rather surprised in answers to another question on SO that someone felt this was inappropriate in C; here's it's not even mentioned, and I'm a little confused and surprised (like "what are they teaching kids in school these days?") about this.
If you use this definition, the memory is allocated statically, neither on the heap nor the stack, but in data space in the image. Thus is neither must be managed as with malloc/free, nor do you have to worry about the address being reused as you would with an auto definition.
It's useful to recall the whole "declared" vs "defined" thing here. Here's an example
/* example.c */
char buf1[256] ; /* declared extern, defined in data space */
static char buf2[256] ; /* declared static, defined in data space */
char * buf3 ; /* declared extern, defined one ptr in data space */
int example(int c) { /* c declared here, defined on stack */
char buf4[256] ; /* declared here, defined on stack */
char * buf5 = malloc(256)] /* pointer declared here, defined on stack */
/* and buf4 is address of 256 bytes alloc'd on heap */
buf3 = malloc(256); /* now buf3 contains address of 256 more bytes on heap */
return 0; /* stack unwound; buf4 and buf5 lost. */
/* NOTICE buf4 memory on heap still allocated */
/* so this leaks 256 bytes of memory */
}
Now in a whole different file
/* example2.c */
extern char buf1[]; /* gets the SAME chunk of memory as from example.c */
static char buf2[256]; /* DIFFERENT 256 char buffer than example.c */
extern char * buf3 ; /* Same pointer as from example.c */
void undoes() {
free(buf3); /* this will work as long as example() called first */
return ;
}
This is incorrect - the array declaration does not require a free. Further, if this is within a function, it is allocated on the stack (if memory serves) and is automatically released with the function returns - don't pass a reference to it back the caller!
Break down your statement
char* name = malloc(256*sizeof(char)); // one statement
char *name; // Step 1 declare pointer to character
name = malloc(256*sizeof(char)); // assign address to pointer of memory from heap
name[2]; // access 3rd item in array
*(name+2); // access 3rd item in array
name++; // move name to item 1
Translation: name is now a pointer to character which is assigned the address of some memory on the heap
char name[256]; // declare an array on the stack
name++; // error name is a constant pointer
*(name+2); // access 3rd item in array
name[2]; // access 3rd item in array
char *p = name;
p[2]; // access 3rd item in array
*(p+2); // access 3rd item in array
p++; // move p to item 1
p[0]; // item 1 in array
Translation: Name is a constant pointer to a character that points to some memory on the stack
In C arrays and pointers are the same thing more or less. Arrays are constant pointers to memory. The main difference is that when you call malloc you take your memory from the heap and any memory taken from the heap must be freed from the heap. When you declare the array with a size it is assigned memory from the stack. You can't free this memory because free is made to free memory from the heap. The memory on the stack will automatically be freed when the current program unit returns. In the second example free(p) would be an error also. p is a pointer the name array on the stack. So by freeing p you are attempting to free the memory on the stack.
This is no different from:
int n = 10;
int *p = &n;
freeing p in this case would be an error because p points to n which is a variable on the stack. Therefore p holds a memory location in the stack and cannot be freed.
int *p = (int *) malloc(sizeof(int));
*p = 10;
free(p);
in this case the free is correct because p points to a memory location on the heap which was allocated by malloc.
depending on where you are running this, stack space might be at a HUGE premium. If, for example, you're writing BREW code for Verizon/Alltel handsets, you are generally restricted to miniscule stacks but have ever increasing heap access.
Also, as char[] are most often used for strings, it's not a bad idea to allow the string constructing method to allocate the memory it needs for the string in question, rather than hope that for ever and always 256 (or whatever number you decree) will suffice.