I have a C++ code...
// global
DWORD* P;
DWORD (*S)[256];
// then later allocate memory
P = new DWORD[18];
S = new DWORD[4][256];
// later on, free memory
delete P;
delete [] S;
that I want to convert to C. I tried ..
/* global */
DWORD* P;
DWORD (*S)[256];
/* allocate */
P = malloc(sizeof(DWORD[18]));
S = malloc(sizeof(DWORD[4][256]));
/* free */
free(P);
free(S);
It works and I don't get any errors or warnings from the compiler (GCC) but I'm not sure if this is the right way, and I'm guessing it leaks memory, probably in freeing the multidimensional array.
Also, are those arrays too big to allocate on the stack? Can I do it like this instead and forget about malloc/free?
DWORD P[18] = {0};
DWORD S[4][256] = {{0}};
That code is perfectly safe. malloc() and free() are only concerned with allocating a number of bytes from the heap. This is why you use sizeof() inside the call to malloc(), to determine the number of bytes that datatype needs. You could also, for example, do S = malloc(sizeof(DWORD) * 4 * 256) and get the same result.
To answer the second half of your question, neither of those arrays are even close to being too big for the stack. You could stack-allocate those in either C or C++.
Related
I'm trying to free the memory of the allocated array inside struct _Stack, but the program keeps crashing
typedef struct _Stack
{
int top;
unsigned int capacity;
int* arr;
}_Stack;
_Stack* createStack(int capacity)
{
_Stack* stack = (_Stack*) malloc(sizeof(_Stack));
stack->capacity = capacity;
stack->top = -1;
stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int)));
return stack;
}
I'm using this function to free the memory, but the program crashes here.
// I have a problem here.
void stack_free(_Stack* stack)
{
free(stack->arr);
free(stack);
}
Change this:
stack->arr = (int*) malloc(sizeof(stack->capacity * sizeof(int)));
to this:
stack->arr = (int*) malloc(stack->capacity * sizeof(int));
since you want the size of the array to be equal to stack->capacity * sizeof(int), and not equal to the size of that expression.
Your program must have invoked Undefined Behavior somewhere in code not shown in the question (because of the wrong size malloc'ed), that's why it crashes later.
PS: Since you use C++, consider using new instead (and delete, instead of free()).
sizeof(stack->capacity * sizeof(int)) in your call to malloc is wrong. Instead of the size of the array, it gives the size of the number used to represent the size of the array. You probably want stack->capacity * sizeof(int).
Another possible problem is that in C you should not cast the return value of malloc, since it can hide other mistakes and cause a crash. See Do I cast the result of malloc?
In C++ you will have to do it, because of the stricter type checking in C++, but it can still hide problems.
These are the problems I see with the code you have shown. However, remember that errors in malloc and free are not necessarily caused by the actual line where they are detected. If some part of your program damages the malloc system's internal data structures, for example by a buffer overrun, the problem can manifest in a much later call to malloc or free, in a completely different part of the program.
Because segmentation fault related to malloc/free happens, I would like to convert malloc/free to new/delete.
Error occurred when malloc/free is converted to below.
Let me know how to solve it.
(original)
char *only_valid_data = static_cast<char*> (malloc (data_size));
(converted)
char *only_valid_data = new static_cast<char*> [data_size];
Just do
char* only_valid_data = new char[data_size];
to allocate.
To free you do
delete[] only_valid_data;
Important note: When you allocate memory with new it will allocate data_size elements, not data_size bytes (like malloc does). The size of an element is the size of the non-pointer base type, in your case e.g. sizeof(*only_valid_data). In this case the element size and the byte size is the same (as sizeof(char) is specified to always be 1), but if the base type is something else it will make a big difference.
For example, if you do
int* int_ptr = new int[10];
then ten integers will be allocated, not ten bytes. This is equivalent to
int* int_ptr = reinterpret_cast<int*>(malloc(10 * sizeof(*int_ptr)));
Also note that for complex types, like structures and classes, allocating with new (or new[]) does more than just allocating memory, it will also make sure that the allocated object(s) constructor is called. The malloc function only allocates memory, it doesn't call the constructor.
Final note: The problem you have with the segmentation fault is probably not caused by your allocation, no matter how you allocate the memory. The problem is more likely because of something else, something you do not show in your question, like writing out of bounds of the allocated memory or dereferencing a null-pointer.
You need run your program in a debugger to catch the crash in action, it will allow you to examine the function call stack, and if the crash doesn't happen in your code then you walk up the call stack until you reach your code. There you can examine the values of variables, to help you understand why the problem occurred.
The malloc family (malloc, realloc, calloc, free) is used almost always in C code, as C++ provides the new and delete operators which are a lot more reliable to use.
A problem with malloc for allocation is that you must specify the size of the type in bytes that you want to allocate. For example:
int* ptr = malloc(5);
Will not allocate space for 5 integers in memory; it will allocate 5 bytes of memory (the size of an integer is 4 bytes, so this would obviously cause problems when assigning).
To do it properly, it must be written as
int* ptr = malloc(5 * sizeof(int));
So that 20 bytes are allocated.
However, there are some exceptions to the case. char, for example only requires one byte of memory, so doing
char* ptr = malloc(5);
Will allocate enough memory to hold 5 characters, and in a way is more valid that writing:
char* ptr = malloc(5 * sizeof(char)); //5 * sizeof(char) == 5 * 1 == 5
However, the free function does not need to know the size of the pointer to be deallocated; a void* is only needed.
Note that in C++, the return of malloc must be cast properly to the type wanted; malloc returns a void* type, but C++ does not allow any pointer to assign a void* to any pointer type like C does:
int* ptr = malloc(5 * sizeof(int)); //valid C code, invalid C++
int* ptr2 = (int*)malloc(5 * sizeof(int)); //valid C code, valid C++
In C++, the new[] operator resolves the issue of remembering to add the sizeof operator.
int* ptr = new int[5];//allocates 5 integers
int* ptr2 = new int(5);//be careful: this allocates a single integer with value of 5
Note that if the new[] operator has been used, the delete[] operator must be used. Otherwise the delete operator must be used:
int* ptr = new int[5];//allocates 5 integers
delete[] ptr;//deallocate the 5 integers
int* ptr2 = new int(5);//be careful: this allocates a single integer with value of 5
delete ptr;//deallocate the integer
The problem with your code is that it does not fit the syntax of the new[] operator
The syntax could be described as:
T* p = new T[size];
Thus your code:
char *only_valid_data = new static_cast<char*> [data_size];
Should be corrected to:
char *only_valid_data = new char[data_size];
As static_cast<char*> is not a type.
Hope this helps :)
I am wondering what is the right/standard way to use malloc and free. Is it needed to set pointer NULL after free? Basically, which of the two following ways is correct?
double* myPtr = (double*)malloc(sizeof(double)*5);
.....
free(myPtr);
or
double* myPtr = (double*)malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL;
Or it should be other ways to use malloc and free? Thanks.
Both are fine. The only difference is that the former approach would crash if you tried to free myPtr a second time.
Depending on the language you're using, the malloc line could be tidied up a little.
Using sizeof(*myPtr) is less prone to bugs when you later refactor. If you're using C, the cast is also unnecessary
double* myPtr = malloc(sizeof(*myPtr)*5);
As pointed out by WhozCraig, if you're using C++, there are much easier ways to allocate an array
std::vector<double> ar(5);
gives you an array of 5 doubles that will grow its storage if required and automatically free its memory when it goes out of scope.
There is no any need to set the pointer to NULL in statement
myPtr = NULL;
On the one hand this prevents the program from an execution error if you will try to free the pointer the second time. On the other hand it maybe hides the bug code where you try to free the pointer the second time.
So whether you need to set the pointer to NULL depends on the program design.
If you are speaking about C++ then it would be better if you would use never C functions malloc and free. Consider using of smart pointers as for example std::shared_ptr.
Setting the pointer back to "NULL" will only be useful if you need to reuse it again later and run checks on it like "if(myPtr) { [...] }". If you don't plan on reusing this specific pointer, you can leave it to whatever his value is.
Use of free:
free() only marks the memory chunk as free - there is no enforcement of this freeing operation. Accessing memory chunks that were previously freed is the cause of many memory errors for novices and experienced programmers. A good practice is that always nullify a pointer that was just freed.
In case of C, just remove the cast:
double* myPtr = malloc(sizeof(double)*5);
.....
free(myPtr);
myPtr = NULL;
You are free to do with Your pointer anything. You don't MUST set it to NULL, but it's good if You don't want to get SEGFAULT for free.
Let see examples.
double * ptr = malloc(sizeof(double) * 42 );
ptr[0] = 1.2; // OK
free (ptr); // OK
ptr = malloc(sizeof(double) * 13); // It's OK. You don't need to set pointer to NULL
Let see some more examples.
void assign(ptr)
{
if( ptr != NULL) ptr[0] = 1.2;
}
double * ptr = NULL;
assign(ptr); // All OK, method will not pass check
double * ptr = malloc(sizeof(double) * 42);
assign(ptr); // OK, method will pass check and assign
free(ptr);
// ptr = NULL; // If we don't do this ....
.... a lot of code and 666 lines below ...
assign(ptr); // BAH! Segfault! And if You assign ptr=NULL, it would not a segfault
What you write is correct (however in C you shouldn't cast the return value of malloc, but in C++ you must do the cast).
You don't have to set myPtr to NULL after calling free. Just don't dereference the memory after if has been freed.
It is best to avoid malloc/free if you can avoid it. You can avoid it if
the array or structure you are allocating is "small" (you can count the size on your fingers) and you know the size at compile time
the array is used and discarded in the local scope of your program
If these are true, don't use malloc/free, but just use local auto variables which are allocated from the stack instead of the heap.
For example, this is simpler and easier to maintain
{
double myPtr[5];
...
}
than this
{
double* myPtr = (double*)malloc(sizeof(double)*5);
...
free(myPtr);
}
It's good practice to use stack variables when you can, because a stack never gets "fragmented" like a heap can. But of course, a stack can overflow, so don't put anything "big" on the stack. Knowing what is "big" is not an exact science; you should know what your stack size is beforehand.
This question already has answers here:
Closed 12 years ago.
Possible Duplicates:
How can I get the size of an array from a pointer in C?
Any tool to find size of memory allocated dynamically using malloc/realloc?
How can I get the size of a pointer of a segment of memory, mallocked by function malloc, if only given a pointer
???
Here is an example:
typedef struct _BlockHeader {
int Size;
} BlockHeader;
void *MyMalloc(int size) {
char *ptr = malloc(size + sizeof(BlockHeader));
BlockHeader *hdr = (BlockHeader*)ptr;
hdr->Size = size;
return (ptr + sizeof(BlockHeader));
}
void MyFree(void *ptr) {
char *myptr = (char*)ptr;
free(myptr - sizeof(BlockHeader));
}
int GetPtrMallocedSize(void *ptr) {
char *myptr = (char*)ptr;
BlockHeader *hdr = myptr - sizeof(BlockHeader);
return (hdr->size);
}
Pratically each memory block starts with an header, collecting memory block information. Of course also realloc and calloc shall be implemented, but memory block cannot be used by other software which expect "normal" malloced memory.
Another way to do this is to hash the pointer, and collect memory information by hooking the malloc/free functions.
I know that MS CRT uses this to keep track of heap overflow and memory leaks. I don't know if there are some sideeffect... actually I've never used it.
You cannot, at least not without knowing the internals of your implementations version of malloc and how it's data structure of allocated blocks looks like.
You can't. Since you allocated the memory in the first place, you're responsible for keeping track of what and how much you allocated.
You get the size of the pointer p with sizeof(p).
If you ask for the size of the memory chunk, that is used to fulfill the malloc call, this might be version specific.
There is no standard for this, so its implementation specific. On windows however, you can use _msize.
I have a program in C++ that has a BYTE array that stores some values. I need to find the length of that array i.e. number of bytes in that array. Please help me in this regard.
This is the code:
BYTE *res;
res = (BYTE *)realloc(res, (byte_len(res)+2));
byte_len is a fictitious function that returns the length of the BYTE array and I would like to know how to implement it.
Given your code:
BYTE *res;
res = (BYTE *)realloc(res, (byte_len(res)+2));
res is a pointer to type BYTE. The fact that it points to a contiguous sequence of n BYTES is due to the fact that you did so. The information about the length is not a part of the pointer. In other words, res points to only one BYTE, and if you point it to the right location, where you have access to, you can use it to get BYTE values before or after it.
BYTE data[10];
BYTE *res = data[2];
/* Now you can access res[-2] to res[7] */
So, to answer your question: you definitely know how many BYTEs you allocated when you called malloc() or realloc(), so you should keep track of the number.
Finally, your use of realloc() is wrong, because if realloc() fails, you leak memory. The standard way to use realloc() is to use a temporary:
BYTE *tmp;
tmp = (BYTE *)realloc(res, n*2);
if (tmp == NULL) {
/* realloc failed, res is still valid */
} else {
/* You can't use res now, but tmp is valid. Reassign */
res = tmp;
}
If the array is a fixed size array, such as:
BYTE Data[200];
You can find the length (in elements) with the commonly used macro:
#define ARRAY_LENGTH(array) (sizeof(array)/sizeof((array)[0]))
However, in C++ I prefer to use the following where possible:
template<typename T, size_t N>
inline size_t array_length(T data[N])
{
return N;
};
Because it prevents this from occurring:
// array is now dynamically allocated
BYTE* data = new BYTE[200];
// oops! this is now 4 (or 8 on 64bit)!
size_t length = ARRAY_LENGTH(data);
// this on the other hand becomes a compile error
length = array_length(data);
If the array is not a fixed size array:
In C++, raw pointers (like byte*) are not bounded. If you need the length, which you always do when working with arrays, you have to keep track of the length separately. Classes like std::vector help with this because they store the length of the array along with the data.
In the C way of doing things (which is also relevant to C++) you generally need to keep a record of how long your array is:
BYTE *res;
int len = 100
res = (BYTE *)realloc(res, (byte_len(len)));
len += 2;
res = (BYTE *)realloc(res, (byte_len(len)));
An alternative in the C++ way of doing things s to use the std::vector container class; a vector has the ability to manage the length of the array by itself, and also deals with the issues of memory management..
EDIT: as others have pointed out the use of realloc here is incorrect as it will lead to memory leaks, this just deals with keeping track of the length. You should probably accept one of the other replies as the best answer
Given the information you seem to have available, there is no way to do what you want. When you are working with arrays allocated on the heap, you need to save the size somewhere if you need to work with it again. Neither new nor malloc will do this for you.
Now, if you have the number of items in the array saved somewhere, you can do this to get the total size in characters, which is the unit that realloc works with. The code would look like this:
size_t array_memsize = elems_in_array * sizeof(BYTE);
If you are really working with C++ and not C I would strongly suggest that you use the vector template for this instead of going to malloc and realloc. The vector template is fast and not anywhere near as error prone as rolling your own memory management. In addition, it tracks the size for you.
When you allocate the pointer initially you also need to keep track of the length:
size_t bufSize = 100;
BYTE* buf = malloc(sizeof(BYTE ) * bufSize);
When you re-allocate you should be carefull with the re-alloc:
BYTE* temp = realloc(buf,sizeof(BYTE ) * (bufSize+2));
if (temp != NULL)
{
bufSize += 2;
buf = temp;
}
If it is a local variable allocated on the stack you can calculate it like this:
BYTE array[] = { 10, 20, 30, ... };
size_t lenght = sizeof(array) / sizeof(BYTE);
If you receive a pointer to the beginning of the array or you allocate it dynamically(on the heap), you need to keep the length as well as the pointer.
EDIT: I also advise you use STL vector for such needs because it already implements dynamic array semantics.