Thinking about returning dynamic or automatic arrays. Not really C-related.
The usual technique to return an array is: A) callee allocates on heap and returns, B) caller allocates on stack and passes to callee.
// A
void caller(void) {
int *a = callee();
free(a);
}
int *callee(void) {
int *a = malloc(10 * sizeof(*a));
return a;
}
// B
void caller(void) {
int a[10]; callee(a, sizeof(a) / sizeof(a[0]));
}
void callee(int *a, size_t n) {
//
}
Case A may lead to unnecessary allocate-free cycle, while case B requires syntactic garbage in caller. In B we also can't compute n in callee, because it comes predefined. We also can't return automatic storage because it will be destroyed on return (accessing it is UB in general).
But what if we introduce new return_auto operator that will return from callee, but leave it's stack frame intact, as if caller did all the job on it's own stack?
// C
void caller(void) {
int *a = callee();
}
int *callee() {
int a[compute_n()];
return_auto a;
}
I mean, caller could inherit callee's stack frame and all issues disappear. It's stack frame would look like this after return_auto:
[caller frame]
arguments
ret-pointer
locals
int *a = callee.a
[callee frame] (defunct)
arguments
ret-pointer
locals
int a[n] (still alive)
[end-of-callee-frame]
[end-of-caller-frame]
In machine code (x86 at least) this may be implemented by jumping to ret-pointer at ss:ebp instead of mov esp, ebp / ret n. We already have VLAs in modern C, and this looks very similar but slightly complex.
Of course that should be used with care, because series of return_auto's would leave pretty huge dump on stack, that will be "collected" only when outermost caller returns (normally). But stack allocations are insanely cheap, and in theory some algorithms could benefit from not calling malloc/free at all. This is also interesting in code structuring perspective, not just performance.
Does anyone know where this technique is implemented / stack frames joined?
(C is just an example here)
Okay, it needs a simple example.
void caller(Context *ct) {
char *s = make_s(ct);
printf("%s\n", s);
}
void make_s(Context *ct) {
const char *tag = "?", *name = "*";
if (ct->use_tag) tag = ct->tag;
else if (ct->app) tag = ct->app->tag;
if (ct->app) name = ct->app->name;
char s[strlen(tag)+strlen(name)+10];
snprintf(s, len, "%s.object(%s)", name, tag);
return_auto s;
}
Obviously, for now we need to explode that in caller's body (probably via macro to feel all caveats) or do asprintf/malloc in callee and free in caller.
This seems a very bad idea for any non-trivial scenario. Just remember a stack frame contains all the local variables along with return address, saved base pointer, and so on. In your model, a caller would need to "inherit" the whole frame as part of its own frame. Then think about you might pass this returned value to some OTHER function. So what if this function wants to return more than just an integral value? You would easily end up with a huge stack frame for main(). Any heap implementation is probably more space efficient.
Related
Below is an example of direct variable declaration.
double multiplyByTwo (double input) {
double twice = input * 2.0;
return twice;
}
Below is an example of dynamic memory allocation.
double *multiplyByTwo (double *input) {
double *twice = malloc(sizeof(double));
*twice = *input * 2.0;
return twice;
}
If I had a choice, I will use direct variable declaration all the time because the code looks more readable. When are circumstances when dynamic memory allocation is more suitable?
When are circumstances when dynamic memory allocation is more suitable?
When the allocation size is not known at compile time, we need to use dynamic memory allocation.
Other than the above case, there are some other scenarios, like
If we want to have a data-structure which is re-sizeable at runtime, we need to go for dynamic memory allocation.
The lifetime of dynamically allocated memory remains valid unless it is free()d. At times, it comes handy when returning some address of a variable from a function call, which , otherwise, with an auto variable, would have been out of scope.
Usually the stack size would be moderately limited. If you want to create and use an huge array, it is better to use dynamic memory allocation. This will allocate the memory from heap.
Dynamic memory allocation with malloc places the memory on the heap, so it is not destroyed when leaving the function.
At a later point you would need to manually free the memory.
Direct declaration lands on the stack and is deleted on leaving the function. What happens on the return statement is that a copy of the variable is made before it is destroyed.
Consider this example:
On heap
void createPeople():
struct person *p = makePerson();
addToOffice(p);
addToFamily(p);
Vs. on stack
void createPeople():
struct person p = makePerson();
addToOffice(p);
addToFamily(p);
In the first case only one person is created and added to office and family. Now if the person is deleted, it is invalidated in both office and family and moreover, if his data is changed, it is changed in both, too.
In the second case a copy of the person is created for the office and family. Now it can happen that you change data of the copy in office and the copy in family remains the same.
So basically if you want to give several parties access to the same object, it should be on the stack.
"If I had a choice, I will use direct variable declaration all the time"
As well you should. You don't use heap memory unless you need to. Which obviously begs the question: When do I need dynamic memory?
The stack space is limited, if you need more space, you'll have to allocate it yourself (think big arrays, like struct huge_struct array[10000]). To get an idea of how big the stack is see this page. Note that the actual stack size may differ.
C passes arguments, and returns values by value. If you want to return an array, which decays into a pointer, you'll end up returning a pointer to an array that is out of scope (invalid), resulting in UB. Functions like these should allocate memory and return a pointer to it.
When you need to change the size of something (realloc), or you don't know how much memory you'll need to store something. An array that you've declared on the stack is fixed in size, a pointer to a block of memory can be re-allocated (malloc new block >= current block size + memcpy + free original pointer is basically what realloc does)
When a certain piece of memory needs to remain valid over various function calls. In certain cases globals won't do (think threading). Besides: globals are in almost all cases regarded as bad practice.
Shared libs generally use heap memory. This is because their authors can't assume that their code will have tons of stack space readily available. If you want to write a shared library, you'll probably find yourself writing a lot of memory management code
So, some examples to clarify:
//perfectly fine
double sum(double a, double b)
{
return a + b;
}
//call:
double result = sum(double_a, double_b);
//or to reassign:
double_a = (double_a, double_b);
//valid, but silly
double *sum_into(double *target, double b)
{
if (target == NULL)
target = calloc(1, sizeof *target);
*target = b;
return target;
}
//call
sum_into(&double_a, double_b);//pass pointer to stack var
//or allocate new pointer, set to value double_b
double *double_a = sum_into(NULL, double_b);
//or pass double pointer (heap)
sum_into(ptr_a, double_b);
Returning "arrays"
//Illegal
double[] get_double_values(double *vals, double factor, size_t count)
{
double return_val[count];//VLA if C99
for (int i=0;i<count;++i)
return_val[i] = vals[i] * factor;
return return_val;
}
//valid
double *get_double_values(const double *vals, double factor, size_t count)
{
double *return_val = malloc(count * sizeof *return_val);
if (return_val == NULL)
exit( EXIT_FAILURE );
for (int i=0;i<count;++i)
return_val[i] = vals[i] * factor;
return return_val;
}
Having to resize the object:
double * double_vals = get_double_values(
my_array,
2,
sizeof my_array/ sizeof *my_array
);
//store the current size of double_vals here
size_t current_size = sizeof my_array/ sizeof *my_array;
//some code here
//then:
double_vals = realloc(
double_vals,
current_size + 1
);
if (double_vals == NULL)
exit( EXIT_FAILURE );
double_vals[current_size] = 0.0;
++current_size;
Variables that need to stay in scope for longer:
struct callback_params * some_func( void )
{
struct callback_params *foo = malloc(sizeof *foo);//allocate memory
foo->lib_sum = 0;
call_some_lib_func(foo, callback_func);
}
void callback_func(int lib_param, void *opaque)
{
struct callback_params * foo = (struct callback_params *) opaque;
foo->lib_sum += lib_param;
}
In this scenario, our code is calling some library function that processes something asynchronously. We can pass a callback function that handles the results of the library-stuff. The lib also provides us with a means of passing some data to that callback through a void *opaque.
call_some_lib_func will have a signature along the lines of:
void call_some_lib_func(void *, void (*)(int, void *))
Or in a more readable format:
void call_some_lib_func(void *opaque, void (*callback)(int, void *))
So it's a function, called call_some_lib_func, that takes 2 arguments: a void * called opaque, and a function pointer to a function that returns void, and takes an int and a void * as arguments.
All we need to do is cast the void * to the correct type, and we can manipulate it. Also note that the some_func returns a pointer to the opaque pointer, so we can use it wherever we need to:
int main ( void )
{
struct callback_params *params = some_func();
while (params->lib_sum < 100)
printf("Waiting for something: %d%%\r", params->lib_sum);
puts("Done!");
free(params);//free the memory, we're done with it
//do other stuff
return 0;
}
Dynamic memory allocation is needed when you intend to transport data out of a local scope (for example of a function).
Also, when you can not know in advance how much memory you need (for example user input).
And finally, when you do know the amount of memory needed but it overflows the stack.
Otherwise, you should not use dynamic memory allocation because of readability, runtime overhead and safety.
I am very new to C so sorry in advance if this is really basic. This is related to homework.
I have several helper functions, and each changes the value of a given variable (binary operations mostly), i.e.:
void helper1(unsigned short *x, arg1, arg2) --> x = &some_new_x
The main function calls other arguments arg3, arg4, arg5. The x is supposed to start at 0 (16-bit 0) at first, then be modified by helper functions, and after all the modifications, should be eventually returned by mainFunction.
Where do I declare the initial x and how/where do I allocate/free memory? If I declare it within mainFunc, it will reset to 0 every time helpers are called. If I free and reallocate memory inside helper functions, I get the "pointer being freed was not allocated" error even though I freed and allocated everything, or so I thought. A global variable doesn't do, either.
I would say that I don't really fully understand memory allocation, so I assume that my problem is with this, but it's entirely possible I just don't understand how to change variable values in C on a more basic level...
The variable x will exist while the block in which it was declared is executed, even during helper execution, and giving a pointer to the helpers allows them to change its value. If I understand your problem right, you shouldn't need dynamic memory allocation. The following code returns 4 from mainFunction:
void plus_one(unsigned short* x)
{
*x = *x + 1;
}
unsigned short mainFunction(void)
{
unsigned short x = 0;
plus_one(&x);
plus_one(&x);
plus_one(&x);
plus_one(&x);
return x;
}
By your description I'd suggest declaring x in your main function as a local variable (allocated from the stack) which you then pass by reference to your helper functions and return it from your main function by value.
int main()
{
int x; //local variable
helper(&x); //passed by reference
return x; //returned by value
}
Inside your helper you can modify the variable by dereferencing it and assigning whatever value needed:
void helper(int * x)
{
*x = ...; //change value of x
}
The alternative is declaring a pointer to x (which gets allocated from the heap) passing it to your helper functions and free-ing it when you have no use for it anymore. But this route requires more careful consideration and is error-prone.
Functions receive a value-wise copy of their inputs to locally scoped variables. Thus a helper function cannot possibly change the value it was called with, only its local copy.
void f(int n)
{
n = 2;
}
int main()
{
int n = 1;
f(n);
return 0;
}
Despite having the same name, n in f is local to the invocation of f. So the n in main never changes.
The way to work around this is to pass by pointer:
int f(int *n)
{
*n = 2;
}
int main()
{
int n = 1;
f(&n);
// now we also see n == 2.
return 0;
}
Note that, again, n in f is local, so if we changed the pointer n in f, it would have no effect on main's perspective. If we wanted to change the address n in main, we'd have to pass the address of the pointer.
void f1(int* nPtr)
{
nPtr = malloc(sizeof int);
*nPtr = 2;
}
void f2(int** nPtr)
{
// since nPtr is a pointer-to-a-pointer,
// we have to dereference it once to
// reach the "pointer-to-int"
// typeof nPtr = (int*)*
// typeof *nPtr = int*
*nPtr = malloc(sizeof int);
// deref once to get to int*, deref that for int
**nPtr = 2;
}
int main()
{
int *nPtr = NULL;
f1(nPtr); // passes 'NULL' to param 1 of f1.
// after the call, our 'nPtr' is still NULL
f2(&nPtr); // passes the *address* of our nPtr variable
// nPtr here should no-longer be null.
return 0;
}
---- EDIT: Regarding ownership of allocations ----
The ownership of pointers is a messy can of worms; the standard C library has a function strdup which returns a pointer to a copy of a string. It is left to the programmer to understand that the pointer is allocated with malloc and is expected to be released to the memory manager by a call to free.
This approach becomes more onerous as the thing being pointed to becomes more complex. For example, if you get a directory structure, you might be expected to understand that each entry is an allocated pointer that you are responsible for releasing.
dir = getDirectory(dirName);
for (i = 0; i < numEntries; i++) {
printf("%d: %s\n", i, dir[i]->de_name);
free(dir[i]);
}
free(dir);
If this was a file operation you'd be a little surprised if the library didn't provide a close function and made you tear down the file descriptor on your own.
A lot of modern libraries tend to assume responsibility for their resources and provide matching acquire and release functions, e.g. to open and close a MySQL connection:
// allocate a MySQL descriptor and initialize it.
MYSQL* conn = mysql_init(NULL);
DoStuffWithDBConnection(conn);
// release everything.
mysql_close(conn);
LibEvent has, e.g.
bufferevent_new();
to allocate an event buffer and
bufferevent_free();
to release it, even though what it actually does is little more than malloc() and free(), but by having you call these functions, they provide a well-defined and clear API which assumes responsibility for knowing such things.
This is the basis for the concept known as "RAII" in C++
Update : Sorry, just a big mistake. It is meaningless to write int *a = 3; But please just think the analogy to the case like TCHAR *a = TEXT("text"); (I edited my question, so some answers and comments are strange, since they are for my original question which is not suitable)
In main function, suppose I have a pointer TCHAR *a = TEXT("text"); Then it excutes the following code:
int i;
for (i = 0; i < 1000; i++) {
a = test(i);
}
with the function TCHAR* test(int par) defined by:
TCHAR* test(int par)
{
TCHAR *b = TEXT("aaa");
return b;
}
My question is, after executing the above code, but before the program ends, in the memory:
1. the pointer `a` remains?
2. The 1000 pointers `b` are deleted each time the function test(...) exits ?
3. But there are still 1000 memory blocks there?
In fact, my question is motivated from the following code, which shows a tooltip when mouse is over a tab item in a tab control with the style TCS_TOOLTIPS:
case WM_NOTIFY
if (lpnmhdr->code == TTN_GETDISPINFO) {
LPNMTTDISPINFO lpnmtdi;
lpnmtdi = (LPNMTTDISPINFO)lParam;
int tabIndex = (int) wParam; // wParam is the index of the tab item.
lpnmtdi->lpszText = SetTabToolTipText(panel->gWin.At(tabIndex));
break;
}
I am thinking if the memory usage increases each time it calls
SetTabToolTipText(panel->gWin.At(tabIndex)), which manipulates with TCHAR and TCHAR* and return a value of type LPTSTR.
Yes, the pointer a remains till we return from the main function
The variable b (a 4-byte pointer) is automatic. It is created each time we call test function. Once we return from it, the variable disappears (the pointer). Please note, the value to which b points isn't affected.
No. In most of the cases, I think, there will be only one block allocated during compilation time (most likely in the read-only memory) and the function will be returning the same pointer on every invocation.
If SetTabToolTipText allocates a string inside using some memory management facilities new/malloc or some os-specific, you should do an additional cleanup. Otherwise there'll be a memory leak.
If nothing like this happens inside (it's not mentioned in the documentation or comments etc), it's most likely returning the pointer to some internal buffer which you typically use as readonly. In this case, there should be no concerns about a memory consumption increase.
You dont allocate any memory so you don't have to worry about memory being freed. When your vaiables go out of scope they will be freed automatically. In this function
int test(int par)
{
int *b = par;
}
you don't have a return value even though the function says that is will return an int, so you should probably do so as in this line
for (i = 0; i < 1000; i++) {
a = test(i);
}
you assign to a the value that is returned by test(). Also
int* a = 3;
int* b = par;
are asking for trouble. You are assigning integer values to a pointer variable. You should probably rethink your above code.
Pointer should contain adress... so int* a = 3 is something meaningless... And in function you don't allocate memory for int (only for par variable, which then destroy when the function ends), you allocate memory for storing adress in int* b, this memory also free when the funciton ends.
I read that there is a funciton called alloca that allocates memory from the stack frame of the current function rather than the heap. The memory is automatically destroyed when the function exits.
What is the point of this, and how is it any different from just crating an array of a structure or a local variable within the function? They would go on the stack and would be destroyed at the end of the function as well.
PS: I saw the other alloca question and it didn't answer how these two things are different :)
When you use alloca, you get to specify how many bytes you want at run time. With a local variable, the amount is fixed at compile time. Note that alloca predates C's variable-length arrays.
With alloca you can create a dynamic array (something that normally requires malloc) AND it's VERY fast. Here there are the advantages and disadvantages of GCC alloca:
http://www.gnu.org/s/hello/manual/libc/Variable-Size-Automatic.html#Variable-Size-Automatic
I think the following are different:
void f()
{
{
int x;
int * p = &x;
}
// no more x
}
void g()
{
{
int * p = alloca(sizeof(int));
}
// memory still allocated
}
Until gcc and C99 adopted Variable-length arrays, alloca offered significantly more power than simple local variables in that you could allocate arrays whose length is not known until runtime.
The need for this can arise at the boundary between two data representations. In my postscript interpreter, I use counted strings internally; but if I want to use a library function, I have to convert to a nul-terminated representation to make the call.
OPFN_ void SSsearch(state *st, object str, object seek) {
//char *s, *sk;
char s[str.u.c.n+1], sk[seek.u.c.n+1]; /* VLA */
//// could also be written:
//char *s,*sk;
//s = alloca(str.u.c.n+1);
//sk = alloca(seek.u.c.n+1);
char *r;
//if (seek.u.c.n > str.u.c.n) error(st,rangecheck);
//s = strndup(STR(str), str.u.c.n);
//sk = strndup(STR(seek), seek.u.c.n);
memcpy(s, STR(str), str.u.c.n); s[str.u.c.n] = '\0';
memcpy(sk, STR(seek), seek.u.c.n); sk[seek.u.c.n] = '\0';
r = strstr(s, sk);
if (r != NULL) { int off = r-s;
push(substring(str, off + seek.u.c.n, str.u.c.n - seek.u.c.n - off)); /* post */
push(substring(str, off, seek.u.c.n)); /* match */
push(substring(str, 0, off)); /* pre */
push(consbool(true));
} else {
push(str);
push(consbool(false));
}
//free(sk);
//free(s);
}
There is also a dangerous usage of alloca, which is easily avoided by prefering VLAs. You cannot use alloca safely within the argument list of a function call. So don't ever do this:
char *s = strcpy(alloca(strlen(t)+1, t);
That's what VLAs are for:
char s[strlen(t)+1];
strcpy(s,t);
Which is considered better style?
int set_int (int *source) {
*source = 5;
return 0;
}
int main(){
int x;
set_int (&x);
}
OR
int *set_int (void) {
int *temp = NULL;
temp = malloc(sizeof (int));
*temp = 5;
return temp;
}
int main (void) {
int *x = set_int ();
}
Coming for a higher level programming background I gotta say I like the second version more. Any, tips would be very helpful. Still learning C.
Neither.
// "best" style for a function which sets an integer taken by pointer
void set_int(int *p) { *p = 5; }
int i;
set_int(&i);
Or:
// then again, minimise indirection
int an_interesting_int() { return 5; /* well, in real life more work */ }
int i = an_interesting_int();
Just because higher-level programming languages do a lot of allocation under the covers, does not mean that your C code will become easier to write/read/debug if you keep adding more unnecessary allocation :-)
If you do actually need an int allocated with malloc, and to use a pointer to that int, then I'd go with the first one (but bugfixed):
void set_int(int *p) { *p = 5; }
int *x = malloc(sizeof(*x));
if (x == 0) { do something about the error }
set_int(x);
Note that the function set_int is the same either way. It doesn't care where the integer it's setting came from, whether it's on the stack or the heap, who owns it, whether it has existed for a long time or whether it's brand new. So it's flexible. If you then want to also write a function which does two things (allocates something and sets the value) then of course you can, using set_int as a building block, perhaps like this:
int *allocate_and_set_int() {
int *x = malloc(sizeof(*x));
if (x != 0) set_int(x);
return x;
}
In the context of a real app, you can probably think of a better name than allocate_and_set_int...
Some errors:
int main(){
int x*; //should be int* x; or int *x;
set_int(x);
}
Also, you are not allocating any memory in the first code example.
int *x = malloc(sizeof(int));
About the style:
I prefer the first one, because you have less chances of not freeing the memory held by the pointer.
The first one is incorrect (apart from the syntax error) - you're passing an uninitialised pointer to set_int(). The correct call would be:
int main()
{
int x;
set_int(&x);
}
If they're just ints, and it can't fail, then the usual answer would be "neither" - you would usually write that like:
int get_int(void)
{
return 5;
}
int main()
{
int x;
x = get_int();
}
If, however, it's a more complicated aggregate type, then the second version is quite common:
struct somestruct *new_somestruct(int p1, const char *p2)
{
struct somestruct *s = malloc(sizeof *s);
if (s)
{
s->x = 0;
s->j = p1;
s->abc = p2;
}
return s;
}
int main()
{
struct somestruct *foo = new_somestruct(10, "Phil Collins");
free(foo);
return 0;
}
This allows struct somestruct * to be an "opaque pointer", where the complete definition of type struct somestruct isn't known to the calling code. The standard library uses this convention - for example, FILE *.
Definitely go with the first version. Notice that this allowed you to omit a dynamic memory allocation, which is SLOW, and may be a source of bugs, if you forget to later free that memory.
Also, if you decide for some reason to use the second style, notice that you don't need to initialize the pointer to NULL. This value will either way be overwritten by whatever malloc() returns. And if you're out of memory, malloc() will return NULL by itself, without your help :-).
So int *temp = malloc(sizeof(int)); is sufficient.
Memory managing rules usually state that the allocator of a memory block should also deallocate it. This is impossible when you return allocated memory. Therefore, the second should be better.
For a more complex type like a struct, you'll usually end up with a function to initialize it and maybe a function to dispose of it. Allocation and deallocate should be done separately, by you.
C gives you the freedom to allocate memory dynamically or statically, and having a function work only with one of the two modes (which would be the case if you had a function that returned dynamically allocated memory) limits you.
typedef struct
{
int x;
float y;
} foo;
void foo_init(foo* object, int x, float y)
{
object->x = x;
object->y = y;
}
int main()
{
foo myFoo;
foo_init(&foo, 1, 3.1416);
}
In the second one you would need a pointer to a pointer for it to work, and in the first you are not using the return value, though you should.
I tend to prefer the first one, in C, but that depends on what you are actually doing, as I doubt you are doing something this simple.
Keep your code as simple as you need to get it done, the KISS principle is still valid.
It is best not to return a piece of allocated memory from a function if somebody does not know how it works they might not deallocate the memory.
The memory deallocation should be the responsibility of the code allocating the memory.
The first is preferred (assuming the simple syntax bugs are fixed) because it is how you simulate an Out Parameter. However, it's only usable where the caller can arrange for all the space to be allocated to write the value into before the call; when the caller lacks that information, you've got to return a pointer to memory (maybe malloced, maybe from a pool, etc.)
What you are asking more generally is how to return values from a function. It's a great question because it's so hard to get right. What you can learn are some rules of thumb that will stop you making horrid code. Then, read good code until you internalize the different patterns.
Here is my advice:
In general any function that returns a new value should do so via its return statement. This applies for structures, obviously, but also arrays, strings, and integers. Since integers are simple types (they fit into one machine word) you can pass them around directly, not with pointers.
Never pass pointers to integers, it's an anti-pattern. Always pass integers by value.
Learn to group functions by type so that you don't have to learn (or explain) every case separately. A good model is a simple OO one: a _new function that creates an opaque struct and returns a pointer to it; a set of functions that take the pointer to that struct and do stuff with it (set properties, do work); a set of functions that return properties of that struct; a destructor that takes a pointer to the struct and frees it. Hey presto, C becomes much nicer like this.
When you do modify arguments (only structs or arrays), stick to conventions, e.g. stdc libraries always copy from right to left; the OO model I explained would always put the structure pointer first.
Avoid modifying more than one argument in one function. Otherwise you get complex interfaces you can't remember and you eventually get wrong.
Return 0 for success, -1 for errors, when the function does something which might go wrong. In some cases you may have to return -1 for errors, 0 or greater for success.
The standard POSIX APIs are a good template but don't use any kind of class pattern.