Integer to string in C without preallocated char array - c

Please, look at the following code that just convert an unsigned int to a string (there may be some unhandled cases but it's not my question), allocating a char array in the heap and returning it, leaving the user the responsibility to free it after the use. Can you explain me why such function (and others similar) do not exist in C standard library? Yes, printf("%s\n", itos(5)) is a memory leak, but this programming pattern is already used and is consider a good practice[1]. IMO, if such functions had existed since the dawn of C we would had little memory leaks more but tons of buffer overflows less!
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
char* itos(unsigned int value)
{
int string_l = (value == 0) ? 1 : (int)log10(value) + 1;
char *string = malloc((string_l + 1) * sizeof(char));
int residual = value;
int it;
for (it = string_l - 1; it >= 0; it--) {
int digit;
digit = residual % 10;
residual = residual / 10;
string[it] = '0' + digit;
}
string[string_l] = '\0';
return string;
}
int main(void)
{
char* string = itos(534534345);
printf("%s\n", string);
free(string);
return 0;
}
[1] http://www.opengroup.org/onlinepubs/009695399/functions/getaddrinfo.html
EDIT:
Habbie's answer:
char *string;
asprintf(&string, "%d", 155);
printf("%s\n", string);
free(string);

turns out asprintf is what you need :)

In my eyes, memory management is up to the caller, not the callee. For instance, when I'm not using the standard malloc() implementation throughout my program I would be very upset about having to find and call the corresponding free(), the upshot is I wouldn't use such a function.
Edit: Your getaddrinfo() example is perfect, they provide both getaddrinfo() and freeaddrinfo(), that's the only way to make sure I'm calling the right free().

Programming has evolved since it was created - this is simply something that wasn't present since the dawn of C, but has evolved in other languages since. I particularly like the way objective-c handles this by returning a string object which has been autoreleased (meaning it will be automatically freed later on, after the object has gone out of scope). You could implement something similar in C if you wanted to:
create a pool for temporary allocations outside your main loop
allocate from the pool as needed using your own allocation function
periodically free the pool at a shallow level in your call stack (for example once per cycle in your very outer main loop)
Another way to achieve the same thing, but allowing you to use system functions that use malloc to allocate memory:
outside your main loop create a list (initially empty) of 'to-be-freed' objects
write a function called 'autofree' that adds pointers to the list and returns the pointer
whenever you need to use it like this: printf("%s\n", autofree(itos(5)));
each time round your main loop, free all the pointers in the list and empty the list
If you do this in a nice way, you can create multiple such autofree pools and nest them around inner loops that potentially create lots of allocations that you want to be freed sooner rather than back in your main loop.

Related

Char Pointers and malloc

I was a bit confused with the concept of char pointers so I made a simple code just printing my name provided by user (me). I also wanted to practice malloc so I referenced the pointer to a certain memory in RAM, but I really didn't know what to put after "sizeof(char) *" because that is the user input, which is not yet decided.
Also, after doing that, I freed the memory, but I got an error message on command line saying:
*** Error in `./char': double free or corruption (fasttop): 0x00000000017fe030 ***
Aborted
It seems like I freed the same memory twice or something, but I don't know what to delete or add. Please help!
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}
The line strings = get_string(); actually assigns the value returned by get_string() to strings. It doesn't write it into the memory you allocated.
So the value returne by malloc() has been overwritten (and lost in this case).
The free(strings) is releasing whatever get_string() returned. The question doesn't provide the code for that but presumably it isn't valid to free() it.
Because the run-time told you it was freed twice I'm guessing you have allocated memory in get_string() then freed it and returned an invalid pointer.
If you want to use the memory you allocated you need to change get_string() to accept a pointer:
void get_string(char *str){
//Do whatever writing you value into str[] as an array of char..
}
Good practice would have:
void get_string(char *str, size_t max){
//Do whatever writing you value into str[] as an array of char..
//Use max to avoid writing beyond the end of the space allocated...
}
Then call as get_string(strings,10);.
EDIT: After a bit of research the flaw has been identified. get_string() doesn't directly free() the string it returns but adds it to a list of allocations made by the library which are freed on exit (in a function called teardown() registered with atexit() or other compiler dependent features).
That is poor design because consumer code is provided no safe way of itself freeing the memory which in a typical use case will not be required for the whole application execution. get_double() is worse because it never returns the allocated data but never reuses it and amounts to a straight memory leak.
The code should either:
Conform to the documentation and require consumer code to free() the string (maybe rename it as say get_string_alloc() for clarity).
Offer a library routine to free the string (get_new_string() and release_string())
There is no very nice way to shift ownership of allocated memory in C but holding onto it for the remainder of execution is definitely not the answer.
Many libraries go round the houses to push allocation onto consumer code but that is onerous when the full size of the space required can't be known such as here.
I'd suggest putting _alloc() at the end of any function that returns objects that consumer code must later free().
So the answer for the question posed is remove the malloc() and the free() because the library handles both. However beware if your program makes many calls to that function and others that internally rely on it (like get_double()) you may run out of memory because the library is sitting on dead space.
The problem is your get_strings overrides your initial malloc. A pointer value is a value. By equating it with something else, you replaced your malloc value.
Memory is allocated at the statement:
strings = get_string();
You dont have to malloc it ( char *strings = malloc(sizeof(char) * 10);
)
Without malloc it will work fine
First You have created a dynamic memory which will be pointed by *strings. But then you are pointing to the local string (from get_string() function) using *strings pointer. when you call free, program is trying delete local (stack) reference and throwing error.
To solve that error, the program should be
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings = malloc(sizeof(char) * 10);
printf("What is your name?\n");
//wait for use to type his/her name
strcpy(strings, get_string()); // Use strcpy instead of assigning
printf("Hello %s\n", strings);
free (strings);
return 0;
}
You don't include the code for get_string(), but you're overwriting strings with its return value which is wrong. The address you pass to free() must come from malloc(), and it seems you're violating that (in addition to losing the original returned address for your 10 bytes).
Assuming get_string() returns static storage (i.e. you don't need to free it) you can do this without involving malloc().
If you really want to, something like this might work:
printf("What is your name?\n");
const char *name = get_string();
const size_t nlen = strlen(name);
char * const name_copy = malloc(nlen + 1);
if(name_copy != NULL)
{
memcpy(name_copy, name, nlen + 1);
printf("Hello %s (from my own memory!)\n", name_copy);
free(name_copy);
}
This is rather convoluted but you get the idea.
char *strings;
No need for new malloc as string returned from get_string() function is already on the heap, you just need to pick up pointer to first character. (get_string() function reference)
strings = get_string();
printf("Hello %s\n", strings);
After printing string you should free memory allocated for it, as it is stated in get_string() function reference
Stores string on heap (via malloc); memory must be freed by caller to
avoid leak.
I think everything else is fine, try this code:
#include <stdio.h>
#include <cs50.h>
int main (void)
{
char *strings;
printf("What is your name?\n");
//wait for use to type his/her name
strings = get_string();
printf("Hello %s\n", strings);
free (strings);
return 0;
}

Declaring arraz with dynamic content

I want to make a program which will say how many big and short letters is in the word and such, but run in to the problem I can't declare content of array dynamically. This is all C code.
I tried this:
char something;
scanf("%c",somethnig);
char somethingmore[]=something;
printf("%c",something[0])
but it wasn't possible to compile I also tried something like this:
char *something;
scanf("%c",something);
printf("%c",something[0]);
which was possible to compile but crushed when called array pointer(I apologize if the naming is wrong) I programing beginner so this is maybe silly question.
This is all just example of problem I run to not code of my program.
Well, disregarding the weirdly wrong syntax in your snippet, I think a good answer comes down to remind you of one thing:
C doesn't do any memory management for you.
Or, in other words, managing memory has to be done explicitly. As a consequence, arrays have a fixed size in C (must be known at compile time, so the compiler can reserve appropriate space in the binary, typically in a data segment, or on the stack for a local variable).
One notable exception is variable length arrays in c99, but even with them, the size of the array can be set only one time -- at initialization. It's a matter of taste whether to consider this a great thing or just a misfeature, but it will not solve your problem of changing the size of something at runtime.
If you want to dynamically grow something, there's only one option: make it an allocated object and manage memory for it yourself, using the functions malloc(), calloc(), realloc() and free(). All these functions are part of standard C, so you should read up on them. A typical usage (not related to your question) would be something like:
#include <stdlib.h>
int *list = 0;
size_t capacity = 0;
size_t count = 0;
void append(int value)
{
if (capacity)
{
if (count == capacity)
{
/* reserve more space, for real world code check realloc()
* return value */
capacity *= 2;
list = realloc(list, capacity * sizeof(int));
}
}
else
{
/* reserve an initial amount, for real world code check malloc()
* return value */
capacity = 16;
list = malloc(capacity * sizeof(int));
}
list[count++] = value;
}
This is very simplified, you'd probably define a container as a struct containing your pointer to the "array" as well as the capacity and count members and define functions working on that struct in some real world code. Or you could go and use predefined containers in a library like e.g. glib.

Weird situation when returning char *

I am pretty new to C programming and I have several functions returning type char *
Say I declare char a[some_int];, and I fill it later on. When I attempt to return it at the end of the function, it will only return the char at the first index. One thing I noticed, however, is that it will return the entirety of a if I call any sort of function on it prior to returning it. For example, my function to check the size of a string (calling something along the lines of strLength(a);).
I'm very curious what the situation is with this exactly. Again, I'm new to C programming (as you probably can tell).
EDIT: Additionally, if you have any advice concerning the best method of returning this, please let me know. Thanks!
EDIT 2: For example:
I have char ret[my_strlen(a) + my_strlen(b)]; in which a and b are strings and my_strlen returns their length.
Then I loop through filling ret using ret[i] = a[i]; and incrementing.
When I call my function that prints an input string (as a test), it prints out how I want it, but when I do
return ret;
or even
char *ptr = ret;
return ptr;
it never supplies me with the full string, just the first char.
A way not working to return a chunk of char data is to return it in memory temporaryly allocated on the stack during the execution of your function and (most probably) already used for another purpose after it returned.
A working alternative would be to allocate the chunk of memory ont the heap. Make sure you read up about and understand the difference between stack and heap memory! The malloc() family of functions is your friend if you choose to return your data in a chunk of memory allocated on the heap (see man malloc).
char* a = (char*) malloc(some_int * sizeof(char)) should help in your case. Make sure you don't forget to free up memory once you don't need it any more.
char* ret = (char*) malloc((my_strlen(a) + my_strlen(b)) * sizeof(char)) for the second example given. Again don't forget to free once the memory isn't used any more.
As MByD correctly pointed out, it is not forbidden in general to use memory allocated on the stack to pass chunks of data in and out of functions. As long as the chunk is not allocated on the stack of the function returning this is also quite well.
In the scenario below function b will work on a chunk of memory allocated on the stackframe created, when function a entered and living until a returns. So everything will be pretty fine even though no memory allocated on the heap is involved.
void b(char input[]){
/* do something useful here */
}
void a(){
char buf[BUFFER_SIZE];
b(buf)
/* use data filled in by b here */
}
As still another option you may choose to leave memory allocation on the heap to the compiler, using a global variable. I'd count at least this option to the last resort category, as not handled properly, global variables are the main culprits in raising problems with reentrancy and multithreaded applications.
Happy hacking and good luck on your learning C mission.

Return a string allocated with malloc?

I'm creating a function that returns a string. The size of the string is known at runtime, so I'm planning to use malloc(), but I don't want to give the user the responsibility for calling free() after using my function's return value.
How can this be achieved? How do other functions that return strings (char *) work (such as getcwd(), _getcwd(), GetLastError(), SDL_GetError())?
Your challenge is that something needs to release the resources (i.e. cause the free() to happen).
Normally, the caller frees the allocated memory either by calling free() directly (see how strdup users work for instance), or by calling a function you provide the wraps free. You might, for instance, require callers to call a foo_destroy function. As another poster points out you might choose to wrap that in an opaque struct, though that's not necessary as having your own allocation and destroy functions is useful even without that (e.g. for resource tracking).
However, another way would be to use some form of clean-up function. For instance, when the string is allocated, you could attach it to a list of resources allocated in a pool, then simply free the pool when done. This is how apache2 works with its apr_pool structure. In general, you don't free() anything specifically under that model. See here and (easier to read) here.
What you can't do in C (as there is no reference counting of malloc()d structures) is directly determine when the last 'reference' to an object goes out of scope and free it then. That's because you don't have references, you have pointers.
Lastly, you asked how existing functions return char * variables:
Some (like strdup, get_current_dir_name and getcwd under some circumstances) expect the caller to free.
Some (like strerror_r and getcwd in under other circumstances) expect the caller to pass in a buffer of sufficient size.
Some do both: from the getcwd man page:
As an extension to the POSIX.1-2001 standard, Linux (libc4, libc5, glibc) getcwd() allocates the buffer dynamically
using malloc(3) if buf is NULL. In this case, the allocated buffer has the length size unless size is zero, when
buf is allocated as big as necessary. The caller should free(3) the returned buffer.
Some use an internal static buffer and are thus not reentrant / threadsafe (yuck - do not do this). See strerror and why strerror_r was invented.
Some only return pointers to constants (so reentrancy is fine), and no free is required.
Some (like libxml) require you to use a separate free function (xmlFree() in this case)
Some (like apr_palloc) rely on the pool technique above.
Many libraries force the user to deal with memory allocation. This is a good idea because every application has its own patterns of object lifetime and reuse. It's good for the library to make as few assumptions about its users as possible.
Say a user wants to call your library function like this:
for (a lot of iterations)
{
params = get_totally_different_params();
char *str = your_function(params);
do_something(str);
// now we're done with this str forever
}
If your libary mallocs the string every time, it is wasting a lot of effort calling malloc, and possibly showing poor cache behavior if malloc picks a different block each time.
Depending on the specifics of your library, you might do something like this:
int output_size(/*params*/);
void func(/*params*/, char *destination);
where destination is required to be at least output_size(params) size, or you could do something like the socket recv API:
int func(/*params*/, char *destination, int destination_size);
where the return value is:
< desination_size: this is the number of bytes we actually used
== destination_size: there may be more bytes waiting to output
These patterns both perform well when called repeatedly, because the caller can reuse the same block of memory over and over without any allocations at all.
There is no way to do this in C. You have to either pass a parameter with size information, so that malloc() and free() can be called in the called function, or the calling function has to call free after malloc().
Many object oriented languages (eg. C++) handle memory in such a way as to do what you want to, but not C.
Edit
By size information as an argument, I mean something to let the called function know the how many bytes of memory are owned by the pointer you are passing. This can be done by looking directly at the called string if it has already been assigned a value, such as:
char test1[]="this is a test";
char *test2="this is a test";
when called like this:
readString(test1); // (or test2)
char * readString(char *abc)
{
int len = strlen(abc);
return abc;
}
Both of those arguments will result in len = 14
However if you create a non populated variable, such as:
char *test3;
And allocate the same amount of memory, but do not populate it, for example:
test3 = malloc(strlen("this is a test") +1);
There is no way for the called function to know what memory has been allocated. The variable len will == 0 inside the 1st prototype of readString(). However, if you change the prototype readString() to:
readString(char *abc, int sizeString); Then size information as an argument can be used to create memory:
void readString(char *abc, size_t sizeString)
{
char *in;
in = malloc(sizeString +1);
//do something with it
//then free it
free(in);
}
example call:
int main()
{
int len;
char *test3;
len = strlen("this is a test") +1; //allow for '\0'
readString(test3, len);
// more code
return 0;
}
You cannot do this in C.
Return a pointer and it is up to the person calling the function to call free
Alternatively use C++. shared_ptr etc
You can wrap it in a opaque struct.
Give the user access to pointers to your struct but not its internal. Create a function to release resources.
void release_resources(struct opaque *ptr);
Of course the user needs to call the function.
You could keep track of the allocated strings and free them in an atexit routine (http://www.tutorialspoint.com/c_standard_library/c_function_atexit.htm). In the following, I have used a global variable but it could be a simple array or list if you have one handy.
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
char* freeme = NULL;
void AStringRelease(void)
{
if (freeme != NULL)
free(freeme);
}
char* AStringGet(void)
{
freeme = malloc(20);
strcpy(result, "A String");
atexit(AStringRelease);
return freeme;
}

Free Dynamically Allocated Array C

I am in a bit of dilemma, thus, first of all I would like to apologize of if the next questions will be a bit more noobish or if they have been asked before (I couldn't find the answers for those though).
Anyway, I will explain it by giving a task as an example (it's not homework, it's just for the sake of my question). Here it goes:
Given a string from stdin index each word, then print each word on one line.
Example:
str[] = "Stack is awesome"
str_index {
[0] => "Stack"
[1] => "is"
[2] => "awesome"
}
I know that there are many ways to solve this, but, again, for the sake of my question
Bare this solution:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
/* fgets adds an unwanted '\n' at the end, so I made
* a special function to read from stdin that removes
* that '\n'.
*/
int read(char *str, int size) {
// fgets adds an unwanted '\n' at the end, so we remove it
fgets(str, size, stdin);
int length = strlen(str);
str[length - 1] = '\0';
return length;
}
/* A function that breaks a string into words, indexes them
* and prints them out, all done dynamically with malloc.
*/
void str_index(char *str) {
char **index, *ptr;
int i = 0, number_of_words;
index = malloc(sizeof(char *));
ptr = strtok(str, " ");
for(i = 0; ptr != NULL; i++) {
index = realloc(index, (i + 1) * sizeof(char *));
index[i] = malloc(50 * sizeof(char));
strcpy(index[i], ptr);
ptr = strtok(NULL, " ");
}
number_of_words = i;
for(i = 0; i < number_of_words; i++) {
printf("%s\n", index[i]);
}
return;
}
int main() {
char str[250];
read(str, 250);
str_index(str);
return 0;
}
QUESTIONS
Where do I have to free the arrays that I have allocated dynamically
in str_index?
Do we have to free them within the function str_index? If so, why?
What I know is that when a function is done executing all local
variables are destroyed.
Why do we have to free them in main? Isn't main a function aswell,
thus upon finishing executing it all variables defined in that function are destroyed.
I'm guessing you are doing a university course. The problem (in my opinion) with university courses is that they start by teaching high level languages where everything is done magically, and then teach you a low level language. If I ruled the world, everyone would start with assembler, then C, then be allowed to 'progress' to Java etc.
To your question, the problem you have is the assumption that 'things might be done magically'. C doesn't do very much magically at all. In particular, if you malloc() or calloc() anything, or allocate anything using something that uses the heap allocator (for instance strdup()), it's your responsibility to free it. And you will need to do that explicitly. If you don't, you will have a memory leak. The first order problem is thus 'if I allocated it, I must ensure it is freed'. The second order problem is 'if I used a library that might have allocated stuff, I need to work out how to ensure it knows I've done, so it can free stuff'. If you bear this in mind, your C programming life will be happy, and valgrind will be your friend.
Let's now consider your questions:
You ask where you should free your dynamically allocated memory. Technically, in this example, you don't need to, because exiting your program will free all memory on the heap. However, let's suppose you want to use this function repeatedly. You want to free the allocation as soon as you no longer have a use for it. In the example presented, that would be immediately before the return. If you had other exits from the function, then make sure you free your allocation before every return. A useful error handling hint is to exit via the same code, and whenever you free() the allocation, also set the pointer to the allocation to NULL. On entry, also initialise the pointer to NULL. Then on exit (a valid use of goto), you can simply check the pointer against NULL, and if it is not null, free() it. (In fact once you get really cocky, you will know free() on NULL on most platforms is a no-op, so you can unconditionally free it). The setting the pointer to NULL bit is to avoid a double free.
This is the difference between the stack and the heap. Local variables are allocated on the stack. C destroys them automatically when a function returns. This is one of the few bits of magic C does. Note that I said it destroys the variables, not the things they point to. So if you have a pointer to allocated (heap) memory in a local variable, and the function returns, it will 'free' the variable (in the sense it will no longer be on the stack), but the allocated (heap) memory will not be freed. This is why you must free heap allocated memory only referenced in a function before the pointers to it are destroyed by exiting the function - see the answer to 1 above.
You don't need to free anything in main() in your example. If you had coded your function to return a pointer to memory on the heap (for instance if you'd coded the equivalent of strdup()) then your main() function would need to free() that. That brings up the important point that what the caller needs to free() depends on how the called function is designed. It's thus important that the called function makes this obvious in documentation.
Where do I have to free the arrays that I have allocated dynamically in str_index?
Just before the return; statement of your function str_index.
Do we have to free them within the function str_index?
Not necessary. Depends on the program requirement.
What I know is that when a function is done executing all local variables are destroyed.
Yes, it is true for space allocated on stack (if variable is not static), but not for the space allocated on heap.
Why do we have to free them in main?
Not necessary that it have to free in main. Depends on the program requirement.

Resources