Consider:
struct foo
{
int a;
int b;
};
void* p = (void*)malloc(sizeof(struct foo));
((foo*)p)->a; // Do something.
free(p); // Is this safe?
Yes.
malloc returns void * and free takes void *, so some of your casts are meaningless, and you're always freeing a void * even if you're starting with some other sort of pointer.
Yes, it's safe. When allocating memory, the runtime library keeps track of the size of each allocation. When you call free(), it looks up the address, and if it finds an allocation for that address, the correct amount of memory is freed (the block that was allocated at that address).
Yes -- free takes a pointer to void, so when you call it, the pointer is (implicitly) cast to a pointer to void in any case.
The rest of your code isn't quite so safe:
void* p = (void*)malloc(sizeof(foo));
You should not cast the return from malloc (in C). This can cover up the mistake of forgetting to #include <stdlib.h>
Yes. The function prototype for free is even:
void free(void *ptr);
In C it is perfectly safe, because there are no destructors to call.
The memory system keeps track of the size of allocations.
In C++ you must delete the same type you new, including using the delete[] operator to delete new'ed arrays.
This is just to make sure destructors are called.
Perhaps it doesn't feel safe because of the magic happening behind the scenes. The C runtime and/or the OS itself is actively tracking the memory returned by malloc including its size and location. See though it feels like you are passing a typeless pointer back to free(), you in fact passing back a reference to an object the memory manager is actively tracking.
yes it is safe.
Yes, but normally it's a sign of poor design.
malloc() is typically used to allocate buffers (large arrays of the same primitive type) or objects (structs with fields initialised). In both cases, the malloc and the free should match so,
unsigned char *rgba_buffer = malloc(width * height * 4);
/* Use the buffer here */
free(rgba_buffer);
BITSTREAM *bs = bitstream("bitfile.boin");
/* Use the bitstream here */
destroy_bitstream(bs);
typedef struct
{
FILE *fp;
unsigned char ch;
int index;
} BITSTREAM;
BITSTREAM *bitstream(const char *filename)
{
BITSTREAM *bs = malloc(sizeof(BITSTREAM));
bs->fp = fopen(filename "rb");
/* etc */
return bs;
}
void destroybitstream(BITSTREAM *bs)
{
if(bs)
{
if(bs->fp)
fclose(bs->fp);
free(bs);
}
}
In one case, malloc and free match, and in the other the allocated memory is returned. There are also secondary resources, and the constructor and destructor match. It should be rare to allocate a region of memory, but not know what it is used for. And you shouldn't be interleaving allocations and frees chaotically.
Modern C++ tightens this all up with unique pointers which "own" the object. While you can have a unique pointer to void, it would be very rare.
Related
I am putting together a project in C where I must pass around a variable length byte sequence, but I'm trying to limit malloc calls due to potentially limited heap.
Say I have a struct, my_struct, that contains the variable length byte sequence, ptr, and a function, my_func, that creates an instance of my_struct. In my_func, my_struct.ptr is malloc'd and my_struct is returned by value. my_struct will then be used by other functions being passed by value: another_func. Code below.
Is this "safe" to do against memory leaks provided somewhere on the original or any copy of my_struct when passed by value, I call my_struct_destroy or free the malloc'd pointer? Specifically, is there any way that when another_func returns, that inst.ptr is open to being rewritten or dangling?
Since stackoverflow doesn't like opinion-based questions, are there any good references that discuss this behavior? I'm not sure what to search for.
typedef struct {
char * ptr;
} my_struct;
// allocates n bytes to pointer in structure and initializes.
my_struct my_func(size_t n) {
my_struct out = {(char *) malloc(n)};
/* initialization of out.ptr */
return out;
}
void another_func(my_struct inst) {
/*
do something using the passed-by-value inst
are there problems with inst.ptr here or after this function returns?
*/
}
void my_struct_destroy(my_struct * ms_ptr) {
free(ms_ptr->ptr);
ms_ptr->ptr = NULL;
}
int main() {
my_struct inst = my_func(20);
another_func(inst);
my_struct_destroy(&inst);
}
I's safe to pass and return a struct containing a pointer by value as you did it. It contains a copy of ptr. Nothing is changed in the calling function. There would, of course, be a big problem if another_func frees ptr and then the caller tries to use it or free it again.
Locality of alloc+free is a best practice. Wherever possible, make the function that allocates an object also responsible for freeing it. Where that's not feasible, malloc and free of the same object should be in the same source file. Where that's not possible (think complex graph data structure with deletes), the collection of files that manage objects of a given type should be clearly identified and conventions documented. There's a common technique useful for programs (like compilers) that work in stages where much of the memory allocated in one stage should be freed before the next starts. Here, memory is only malloced in big blocks by a manager. From these, the manager allocs objects of any size. But it knows only one way to free: all at once, presumably at the end of a stage. This is a gcc idea: obstacks. When allocation is more complex, bigger systems implement some kind of garbage collector. Beyond these ideas, there are as many ways to manage C storage as there are colors. Sorry I don't have any pointers to references (pun intended :)
If you only have one variable-length field and its size doesn't need to be dynamically updated, consider making the last field in the struct an array to hold it. This is okay with the C standard:
typedef struct {
... other fields
char a[1]; // variable length
} my_struct;
my_struct my_func(size_t n) {
my_struct *p = malloc(sizeof *p + (n - 1) * sizeof p->a[0]);
... initialize fields of p
return p;
}
This avoids the need to separately free the variable length field. Unfortunately it only works for one.
If you're okay with gcc extensions, you can allocate the array with size zero. In C 99, you can get the same effect with a[]. This avoids the - 1 in the size calculation.
In my project have a sub-function. In this function, I need to store my data temporarily. So I use malloc(), I'm not sure whether is necessary to use free()?
void *hash2(unsigned char *mes, element_t d)
{
size_t iterations = strlen(mes) / 8;
unsigned char *rtemp = malloc(32 * sizeof(char));
SHA256(mes, iterations, rtemp);
element_from_hash(d, rtemp, 32);
free(rtemp);
}
As already stated in the present answer, you should free any memory that is no longer needed, if you allocate memory within the function, not freeing it and not returning any pointer to it will cause a memory leak.
Note that your function *hash2(...), having void* return type, must return a value, if you don't need it to, use void instead.
In your particular code it does seem that you wouldn't need to use malloc anyway, you can use a local array unsigned char rtemp[32];. malloc is a heavy function that involves system calls, if you can avoid it, you should.
Yes, as you are not using the allocated memory anymore, you must free it.
Once you return from the function call, you'll have no way to access the allocated memory, hence it cannot be freed up. So, you need to to pass the pointer to free() before leaving the function scope (as seen in the snippet) to avoid memory leak.
I need to allocate all the memory my application will use up front. And then whenever needed overwrite that memory with data I need to do computations on. The memory has to be allocated first before any computations because I'm trying to run a multi-threaded CUDA algorithm in parallel as explained in my question here (Multi-Threaded CPU CUDA application not asynchronous when calling CudaFree).
I thought I could allocate all the memory needed as a byte pointer and then store that pointer as a void pointer:
void * allocateMemory()
{
byte *mem;
int nbytes = 13107200;
mem = (byte *) malloc(nbytes);
return mem;
}
Later in my program I want to use the memory that's already allocated to store data. I don't know ahead of time what type the data will be but I know it's size won't go over the allocated limit.
void doSomething(void * mem)
{
int *a = (int*) mem;
for (int i = 0; i < 100; i++)
{
a[i] = i;
}
//do stuff
}
There are many other functions like doSomething(void * mem) above but that use type double or type float or maybe even type byte. I need to be able to overwrite the orignally allocated memory with whatever data type I need. The above code does not work because it says I can't deference a void pointer. It also says I attempted to read or write protected memory.
What is the proper way to do this? What is the best way to accomplish my goal of having all my memory allocated at the beginning and then used however necessary throughout? Thanks!
It sounds like you have two problems.
Cannot dereference a void pointer. Somewhere in your code you have used the result from allocateMemory() without a cast. The code you give is OK, but whatever line the compiler is flagging as wrong is not OK. For example, maybe you have:
void *foo = allocateMemory();
foo[42]; // compiler doesn't have a real type here - error
((int*)foo)[42]; // compiler happy
Attempted to access protected memory. Somewhere in your code you have an invalid pointer. The most likely cause is that allocateMemory() is returning NULL (which you are not checking for).
Your general approach seems OK to me; the issues you describe are related to details in your code, not the overall idea.
In C, it is possible for functions to return pointers to memory that that function dynamically-allocated and require the calling code to free it. It's also common to require that the calling code supplies a buffer to a second function, which then sets the contents of that buffer. For example:
struct mystruct {
int a;
char *b;
};
struct mystruct *get_a_struct(int a, char*b)
{
struct mystruct *m = malloc(sizeof(struct mystruct));
m->a = a;
m->b = b;
return m;
}
int init_a_struct(int a, char*b, struct mystruct *s)
{
int success = 0;
if (a < 10) {
success = 1;
s->a = a;
s->b = b;
}
return success;
}
Is one or the other method preferable? I can think of arguments for both: for the get_a_struct method the calling code is simplified because it only needs to free() the returned struct; for the init_a_struct method there is a very low likelihood that the calling code will fail to free() dynamically-allocated memory since the calling code itself probably allocated it.
It depends on the specific situation but in general supplying the allocated buffer seems to be preferable.
As mentioned by Jim, DLLs can cause problems if called function allocates memory. That would be the case if you decide to distribute the code as a Dll and get_a_struct is exported to/is visible by the users of the DLL. Then the users have to figure out, hopefully from documentation, if they should free the memory using free, delete or other OS specific function. Furthermore, even if they use the correct function to free the memory they might be using a different version of the C/C++ runtime. This can lead to bugs that are rather hard to find. Check this Raymond Chen post or search for "memory allocation dll boundaries". The typical solution is export from the DLL your own free function. So you will have the pair: get_a_struct/release_a_struct.
In the other hand, sometimes only the called function knows the amount of memory that needs to be allocated. In this case it makes more sense for the called function to do the allocation. If that is not possible, say because of the DLL boundary issue, a typical albeit ugly solution is to provide a mechanism to find this information. For example in Windows the GetCurrentDirectory function will return the required buffer size if you pass 0 and NULL as its parameters.
I think that providing the already allocated struct as an argument is preferable, because in most cases you wouldn't need to call malloc/calloc in the calling code, and therefore worrying about free'ing it. Example:
int init_struct(struct some_struct *ss, args...)
{
// init ss
}
int main()
{
struct some_struct foo;
init_struct(&foo, some_args...);
// free is not needed
}
The "pass an pointer in is preferred", unless it's absolutely required that every object is a "new object allocated from the heap" for some logistical reason - e.g. it's going to be put into a linked list as a node, and the linked-list handler will eventually destroy the elements by calling free - or some other situation where "all things created from here will go to free later on).
Note that "not calling malloc" is always the preferred solution if possible. Not only does calling malloc take some time, it also means that some place, you will have to call free on the allocated memory, and every allocated object takes several bytes (typically 12-40 bytes) of "overhead" - so allocating space for small objects is definitely wasteful.
I agree with other answers that passing the allocated struct is preferred, but there is one situation where returning a pointer may be preferred.
In case you need to explicitly free some resource at the end (close a file or socket, or free some memory internal to the struct, or join a thread, or something else that would require a destructor in C++), I think it may be better to allocate internally, then returning the pointer.
I think it so because, in C, it means some kind of a contract: if you allocate your own struct, you shouldn't have to do anything to destroy it, and it be automatically cleared at the end of the function. On the other hand, if you received some dynamically allocated pointer, you feel compelled to call something to destroy it at the end, and this destroy_a_struct function is where you will put the other cleanup tasks needed, alongside free.
Think of a pointer-datatype, for instance to a floating-pointer number.
typedef float* flPtrt;
How would I allocate an array of 3 elements in the local scope? I guess using malloc and free withing the same scope produces overhead, but what's the alternative?
void foo() {
flPtrt ptr = malloc(sizeof(float)*3);
// ...
free(ptr);
}
If 3 is known at compile time and is small enough, you can declare a local array and use it as a pointer
void foo() {
float array[3];
flPtrt ptr = array;
}
If the size is bigger or variable, you have to use dynamic memory as in your example.
I think what your'e looking for is the alloca() function.
I'm not sure it's standard C, but it exists in GNU, and it worked on my visual studio.
So this is how you use it:
int n = 5;
int* a = (int*) alloca(sizeof(int) * n);
It creates an array of elements on the stack (rather than on the heap with malloc).
Advantages: less overhead, no need to free manually (when you return from your method, the stack folds back and the memory is lost)
Disadvantage: If you want to return a pointer from a method NEVER use alloca, since you will be pointing at something that no longer exists after exiting the function. One can also argue that the stack is usually smaller than the heap, so if you want larger space use malloc.
See more here
If you know the required size of the array ahead of time, you could just allocate it as a stack variable and avoid heap memory management.
Otherwise, the approach you outlined is appropriate and there is not really an alternative.
Use an array.
void foo(void) // note that "void foo()" is obsolete
{
float data[3];
float *ptr = data;
// ...
}