ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
By having it return the a variable that is dynamically allocate, I cannot free this memory. So every time it gets called, I am leaking away MAX_SIZE_IPADD + 1.
Can anyone think of a way around this, short of passing a char* to the function to store the value in?
You can always just free() the value returned by this function whenever you're done with it; since the return value ("answer") is just the pointer to the memory you allocated.
There are a couple of cardinal rules to malloc/free
(1) One free per malloc.
(2) Only ever pass free a pointer you got with malloc. Passing it other stuff will lead to weird results (and program crashes).
So, yes, you can malloc some memory in one function and free it in another function. But don't do something like:
Dpo you see why? That code called malloc twice (on the same pointer, but freed only the second chunk. The first chunk was effectively lost, and this is bad.
char *a;
char *b;
b = malloc( someValue );
a =b;
free( a );
would work just fine. Since, after all, it's just a memory location, passing it to free by whatever name would have the same effect--assuming that memory address had been malloc'd in the first place.
IMO, your best bet would be to pass int_to_dotted() a pointer to a chunk of memory, along with the size of that chunk; that way you can keep any calls to malloc() and free() in the calling function, which might help with debugging. This seems to be the convention for thread-safe functions in glibc.
you might as well pass the malloc()'d pointer to int_to_dotted() and save an sprintf() (I'd recommend that you use snprintf(), BTW), as well saving an additional block of memory, of size (MAX_SIZE_IPADDR + 1). Just a thought.
Also, I'm interested to know why you are casting the result of malloc(), it shouldn't be necessary.
Code:
void int_to_dotted( unsigned int ipv4, char *answer, unsigned int answer_len ) {
int remainder = 0;
int octet1 = 0, octet2 = 0, octet3 = 0;
unsigned int FIRST_OCT_MULTIPLIER = 16777216;
unsigned int SECOND_OCT_MULTIPLIER = 65536;
unsigned int THIRD_OCT_MULTIPLIER = 256;
octet1 = ipv4 / FIRST_OCT_MULTIPLIER;
ipv4 %= FIRST_OCT_MULTIPLIER;
printf( "ipv4 = %d\n", ipv4 );
octet2 = ipv4 / SECOND_OCT_MULTIPLIER;
ipv4 %= SECOND_OCT_MULTIPLIER;
printf( "ipv4 = %d\n", ipv4 );
octet3 = ipv4 / THIRD_OCT_MULTIPLIER;
ipv4 %= THIRD_OCT_MULTIPLIER;
printf( "octet1 = %d, o2 = %d, o3 = %d, o4 = %d\n", octet1, octet2, octet3, ipv4 );
snprintf( answer, answer_len, "%d.%d.%d.%d", octet1, octet2, octet3, ipv4 );
printf( "answer = %s\n", answer );
}
int callingFunction( void ) {
char *ip;
ip = malloc( MAX_SIZE_IPADDR );
/* malloc error check */
int_to_dotted( someInt, ip, MAX_SIZE_IPADDR );
/* Do something with ip */
if ( ip != NULL ) {
free( ip );
ip = NULL;
}
/* Rest of fn */
}
you might as well pass the malloc()'d pointer to int_to_dotted() and save an sprintf() (I'd recommend that you use snprintf(), BTW), as well saving an additional block of memory, of size (MAX_SIZE_IPADDR + 1).
Well, that makes sense, and honestly, I don't know why I didn't just do that from the beginning.
What is the point of setting the pointer equal to NULL after it is freed? Is that to prevent accidentally trying to access the formerly pointed-to memory again?
And casting the return value of malloc()? I've always done that, as that was highly recommended in the book in which I initially learned how to use malloc, "Linux Programming by Example" by Arnold Robbins:
Quote:
Allocate the storage by calling malloc(), assigning the function's return value to the pointer variable. It is good practice to cast the return value of malloc() to that of the variable being assigned to. In C it's not required (although the compiler may generate a warning). We strongly recommend always casting the return value.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.