What's the equivalent of new/delete of C++ in C?
Or it's the same in C/C++?
There's no new/delete expression in C.
The closest equivalent are the malloc and free functions, if you ignore the constructors/destructors and type safety.
#include <stdlib.h>
int* p = malloc(sizeof(*p)); // int* p = new int;
...
free(p); // delete p;
int* a = malloc(12*sizeof(*a)); // int* a = new int[12];
...
free(a); // delete[] a;
Note that constructors might throw exceptions in C++. The equivalent of player* p = new player(); would be something like this in C.
struct player *p = malloc(sizeof *p);
if (!p) handle_out_of_memory();
int err = construct_player(p);
if (err)
{
free(p);
handle_constructor_error();
}
The equivalent of delete p is simpler, because destructors should never "throw".
destruct(p);
free(p);
Use of new and delete in C++ combines two responsibility - allocating/releasing dynamic memory, and initialising/releasing an object.
As all the other answers say, the most common way to allocate and release dynamic memory is calling malloc and free. You also can use OS-specific functions to get a large chunk of memory and allocate your objects in that, but that is rarer - only if you have fairly specific requirements that malloc does not satisfy.
In C, most APIs will provide a pair of functions which fulfil the other roles of new and delete.
For example, the file api uses a pair of open and close functions:
// C++
fstream* fp = new fstream("c:\\test.txt", "r");
delete fp;
// C
FILE *fp=fopen("c:\\test.txt", "r");
fclose(fp);
It may be that fopen uses malloc to allocate the storage for the FILE struct, or it may statically allocate a table for the maximum number of file pointers on process start. The point is, the API doesn't require the client to use malloc and free.
Other APIs provide functions which just perform the initialisation and releasing part of the contract - equivalent to the constructor and destructor, which allows the client code to use either automatic , static or dynamic storage. One example is the pthreads API:
pthread_t thread;
pthread_create( &thread, NULL, thread_function, (void*) param);
This allows the client more flexibility, but increases the coupling between the library and the client - the client needs to know the size of the pthread_t type, whereas if the library handles both allocation and initialisation the client does not need to know the size of the type, so the implementation can vary without changing the client at all. Neither introduces as much coupling between the client and the implementation as C++ does. (It's often better to think of C++ as a template metaprogramming language with vtables than an OO language)
Not directly an exact replica but compatible equivalents are malloc and free.
<data-type>* variable = (<data-type> *) malloc(memory-size);
free(variable);
No constructors/destructors - C anyway doesn't have them :)
To get the memory-size, you can use sizeof operator.
If you want to work with multidimensional arrays, you will need to use it multiple times (like new):
int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12.
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc
Use malloc / free functions.
Late, but I really like this syntax, although I'm not sure if it fits ways of C
#include <stdlib.h>
#define new(type, length) malloc(sizeof(type)*(length))
#define delete(x) free(x)
int main()
{
int *test = new(int, 30);
delete(test);
}
Related
I am changing my language from c++ to c and want to use new, however, c doesn't allow the use of new, so i have to use malloc.
malloc(sizeof(*ThreadNum))
the line above does not work when i tried to do it myself and have run out of options. This is the line that i wish to switch. Any tips would be lovely:)
for(i=0; i <NUM_THREADS; i++){
ThreadS [i] = new struct ThreadNum; //allocating memory in heap
(*ThreadS[i]).num = num;
(*ThreadS[i]).NumThreads = i;
pthread_t ID;
printf("Creating thread %d\n", i); //prints out when the threads are created
rc = pthread_create(&ID, NULL, print, (void *) ThreadS[i]); //creates the threads
First thing you need to consider is that new and malloc() are not equivalents. Second thing is that ThreadNum is a struct so you may want to write sizeof(struct ThreadNum) but usually a better choice is like this
ThreadNum *thread_num = malloc(sizeof(*thread_num));
note that above thread_num is not a type or struct, it's a variable and has pointer type. Using * before it means that you want the size of the type with one less level of indirection.
Getting back to my first comment, new does not only allocate memory but it also invokes the object constructor, which is something that does not exist in c.
In c you have to do all the initialization by hand and after checking that malloc() did return a valid pointer.
I am trying to build a stack that resizes itself and realloc() crashes my program.
Constructor:
Stack::Stack()
{
st = (int*)malloc(sizeof(int));
sp = 0;
length = 1;
}
This is my add() function:
void Stack::add(int item)
{
if (sp == length)
Stack::resizeStack(&st, &length, 1);
st[sp++] = item;
}
Resize function (I use the variable a in order to be able to reuse it for pop) :
void Stack::resizeStack(int **st, int *length, bool a)
{
if (a == 1)
*length *= 2;
else
*length /= 2;
realloc(*st, sizeof(int) * (*length));
}
This is how I test my stack:
Stack* myStack = new Stack();
for (int i = 0; i < 10; i += 1) {
myStack->add(i);
cout << myStack->getStackSize() << '\n';
}
free(myStack);
I have noticed that the program crashes at the end of the for.
I would appreciate if someone explained what I am doing wrong.
All those people who say, malloc() and free() are a bad idea in C++ are 100% correct. Prefer new and delete over malloc() and free() and prefer standard library containers over your own homebrew stack implementation.
Anyway, the real issue here is, that realloc() might allocate a new memory block and free the old one. It returns a pointer to the new one.
The correct call is:
*st = realloc(*st, sizeof(int) * (*length));
Now *st will store the new pointer and everything is all right.
Consider to use the standard library, instead of implementing your own fundamental data structures. It has a well designed interface, and is very thoroughly tested.
You are lucky that you get a crash. This is undefined behavior.
Let's see what Bjarne Stroustrup says about this from here:
No, in the sense that you cannot allocate an object with malloc() and
free it using delete. Nor can you allocate with new and delete with
free() or use realloc() on an array allocated by new.
The C++ operators new and delete guarantee proper construction and
destruction; where constructors or destructors need to be invoked,
they are. The C-style functions malloc(), calloc(), free(), and
realloc() doesn't ensure that. Furthermore, there is no guarantee that
the mechanism used by new and delete to acquire and release raw memory
is compatible with malloc() and free(). If mixing styles works on your
system, you were simply "lucky" - for now.
C++ FAQ has also special entry for this:
https://isocpp.org/wiki/faq/freestore-mgmt#realloc-and-renew
Crashing at the end is most likely because you're mixing new with free. This is undefined behaviour. It may work on some systems, but is never a good idea. You should pair new with delete. Calls to malloc are paired with free, but these are more for C code. C++ code usually uses new and delete.
Of course you can eliminate the new by making myStack a local variable:
Stack myStack;
You would also need to adjust member access to use . instead of ->. There would be no need to delete myStack, since local variables would be automatically cleaned up once the function exits, including in the case of exceptions.
Also noticed the return value of realloc is ignored. If the current memory block can't be extended by realloc, it must allocate a new memory block and copy the old data over to it. A new pointer is returned in this case, so st must be updated.
*st = realloc(*st, sizeof(int) * (*length));
But again, using malloc, realloc, and free is a bit odd in C++ code.
You can use new[] and delete[] if you're forced to use manual memory management of arrays (such as for learning), or you can use the vector or stack classes for more serious code.
Use std::vector and it will automatically take care of all the memory management for you. In fact, you pretty much just don't need a Stack class in the face of std::stack but that's another matter.
Furthermore for the test do not allocate the Stack dynamically in a super pointless way, just make a local Stack.
I would like to allocate 2D array and I am considering two possibilities (avr-gcc on Arduio):
A:
int **arr = new int*[5];
for(int i = 0 ; i < 5 ; i++){
arr[i] = new int[10];
}
B:
int **arr = malloc(5 * sizeof(int *));
for(int i = 0 ; i < 5 ; i++) {
arr [i] = malloc(10* sizeof(int))
}
Is there any difference between A and B? Would the compiler create the same byte code in those two cases (arv-gcc)?
In C, you can't allocate memory by new, because there is no such thing. For C++, you may prefer new for couple of reasons such as:
exceptions (unless you add (std::nothrow) explicitly)
initializer lists (since C++11)
better safety as it returns pointer of proper type (specifically not void *)
cleaner syntax (but that is purely subjective)
See In what cases do I use malloc and/or new? for more discussion on that matter.
If you want to allocate a two-dimensional array and the rightmost size is known at compile-time (i.e. it is a constant expression - constexpr), then you don't need to loop over.
New in C++
int (*arr)[10] = new int [2][10];
If you want it to be pre-set with zeros (that is, like std::calloc), then use:
int (*arr)[10] = new int [2][10]{0}; // C++11
int (*arr)[10] = new int [2][10](); // C++03
Just like for any arrays allocated by new[], there is a corresponding delete[] operator to free it:
delete[] arr;
Malloc in C and C++
int (*arr)[10] = malloc(5 * sizeof(*arr));
This allocates array, that is like arr[5][10] (only in sense of indices).
To access its elements in both simply use:
arr[a][b]
To free it, you basically do:
free(arr);
In C++ you additionally need to take care of cast and possibly qualify it with std, so it's std::malloc (especially if includes cstdlib, as stdlib.h header is deprecated in C++ Standard):
const int N = 10;
int (*arr)[N] =
static_cast<int (*)[N]>(std::malloc(5 * sizeof(*arr)));
but I don't think that you will like it.
If you're using a C++ compiler (and Arduino sketches are C++), you should probably prefer new. It's unlikely to matter for doing a simple int array but I'd leave C legacy stuff only for code that has to run in a C environment.
There's absolutely no reason nowadays for C+ programmers (that curious breed of programmer which never whole-heartedly transitions from C to C++) to exist :-)
A and B are basically equivalent.
The compiler may or may not create the same code (not byte code BTW). But often using the new operator simply boils down to a call to malloc. To find out, compile your program with gcc -S and have a look at the assembly output.
But for c++ programs you should prefer new to malloc.
Consider the following code
struct foo
{
const int txt_len;
const int num_len;
char * txt;
int * num;
foo(int tl, int nl): txt_len(tl), num_len(nl)
{
char * tmp = new char[txt_len * sizeof(char) + num_len * sizeof(int)];
txt = new (tmp) char [txt_len * sizeof(char)];
num = new (tmp + txt_len * sizeof(char)) int[num_len * sizeof(int)];
// is this the same as above?
// txt = tmp;
// num = (int *) (tmp + txt_len * sizeof(char));
}
~foo()
{
delete[] txt; // is this the right way to free the memory?
}
};
I want *txt and *num to be contiguous, is that the best way to do it?
also is there any difference between placement new and pointer arithmetic? which one should I use?
If you want a contiguous block of memory, you have to allocate it whole with a single call to operator new[] or malloc() or similar. Multiple calls to these functions do not guarantee any contiguity of allocated blocks whatsoever. You may allocate a big block and then carve parts from it as needed.
And you should delete and free() all blocks previously allocated with new and malloc(), otherwise you'll leak memory and probably make your program unstable (it will fail to allocate more memory at some point) and exert unnecessary pressure on memory in the OS, possibly slowing down other programs or making them unstable as well.
Placement new, however, does not actually allocate any memory. It simply constructs an object at the specified location and so you don't need to free that memory twice.
One problem that I see in your code is that it doesn't align ints. On some platforms reading or writing integers bigger than 1 byte from/to the memory must be aligned and if it's not, you can either read/write values from/to wrong locations or get CPU exceptions leading to termination of your program. The x86 is very permissive in this regard and won't mind, though may tax you with degraded performance.
You'll need to put the int data first, due to the alignment issues. But we can't then do delete num[] as the type is wrong - it must be cast to a char* before deleting.
char * tmp = new char[num_len * sizeof(int) + txt_len * sizeof(char)];
num = new (tmp) int[num_len];
txt = new (tmp + num_len * sizeof(int)) char [txt_len];
(This makes liberal use of the fact that sizeof(char)==1)
You might be tempted to do delete[] num, but num is of type int*, and it was new'ed as a char*. So you need to do;
delete[] (char*) num;
This is the same as long as you use POD types. And your delete is fine.
However, as David's comment states, you need to consider alignment problems.
Placement new is mostly use when you want to call constructor of class/struct on some preallocated memory blocks.
But for native types it makes no different to use placement new & pointer arithmetic.
Please correct me if I was wrong.
If txt and num always point to int and char, other built in types or other types not requiring construction, then no. You don't need placement new.
If on the other hand you were to change one of them to a class which requires construction, i.e. changes txt to type std::string, then using placement new is necessary.
Placement new allows you to call the constructor, building, if you like, the object at that address. Built in types have default constructors that do nothing if your not initializing.
In both cases you need to do pointer arithmetic, just one way you store the answer in a pointer, the other you pass the answer to placement new which gives it back to you for storage in the pointer, and then calls the constructor.
I'm catching up on pointers. I wrote down a few lines of code to test the different ways I could dynamically allocate a 2d array (posted at the bottom)
My questions are the following:
Should I use malloc in c++, or new? If I use new, can I still use realloc?
When should I use realloc? What are the implications of using it in terms of performance and bugs?
Out of the examples bellow, which objectNew version should I use? If the answer depends on the application, what are does it depend on?
Many thanks,
Matt
#include <stdio.h>
#include <stdlib.h>
struct myObject
{
int data;
myObject(int i)
{
data = i;
}
myObject()
{
data = 0;
}
};
int main(){
int r = 7;
int c = 6;
printf("Objects using NEW===============================\n");
//notice the triple pointer being assigned a new double pointer array
myObject*** objectNew = new myObject** [r];
for(int i=0;i<r;i++)
{
//objectNew is a 1D array of double pointers, however if we assign another layer of pointers, it becomes a 2D array of pointers to myObject
objectNew[i] = new myObject* [c];
for(int j=0;j<c;j++){
objectNew[i][j] = new myObject(10*i+j);
//notice that we dereference data (->)
printf("objectNew[%2d][%2d]=%02d\n",i,j,objectNew[i][j]->data);
}
}
delete objectNew;
printf("Objects using NEW version 2===============================\n");
//notice the triple pointer being assigned a new double pointer array
myObject** objectNew2 = new myObject* [r];
for(int i=0;i<r;i++)
{
//objectNew is a 1D array of double pointers, however if we assign another layer of pointers, it becomes a 2D array of pointers to myObject
objectNew2[i] = new myObject [c];
for(int j=0;j<c;j++){
objectNew2[i][j] = myObject(10*i+j);
//notice that we dereference data (->)
printf("objectNew2[%2d][%2d]=%02d\n",i,j,objectNew2[i][j].data);
}
}
delete objectNew2;
printf("Objects using MALLOC===============================\n");
//notice the double pointer being allocated double pointers the size of pointers to myObject
myObject** objectMalloc =(myObject**) malloc(sizeof(myObject*)*r);
for(int i=0;i<r;i++)
{
//now we are assigning array of pointers the size of myObject to each double pointer
objectMalloc[i] = (myObject*) malloc(sizeof(myObject)*c);
for(int j=0;j<c;j++){
objectMalloc[i][j] = myObject(10*i+j);
//notice that we access data without dereferencing (.)
printf("objectMalloc[%2d][%2d]=%02d\n",i,j,objectMalloc[i][j].data);
}
}
free((void*) objectMalloc);
//same as Malloc
printf("Objects using CALLOC===============================\n");
myObject** objectCalloc = (myObject**) calloc(r,sizeof(myObject*));
for(int i=0;i<r;i++)
{
objectCalloc[i] = (myObject*) calloc(c,sizeof(myObject));
for(int j=0;j<c;j++){
objectCalloc[i][j] = myObject(10*i+j);
printf("objectCalloc[%2d][%2d]=%02d\n",i,j,objectCalloc[i][j].data);
}
}
free((void*) objectCalloc);
printf("Int using NEW===============================\n");
//int is not an object
int** intNew = new int* [r];
for(int i=0;i<r;i++)
{
intNew[i] = new int[c];
for(int j=0;j<c;j++){
intNew[i][j] = 10*i+j;
printf("intNew[%2d][%2d]=%02d\n",i,j,intNew[i][j]);
}
}
delete intNew;
printf("Int using malloc===============================\n");
int** intMalloc =(int**) malloc(sizeof(int*)*r);
for(int i=0;i<r;i++)
{
intMalloc[i] =(int*) malloc(sizeof(int)*c);
for(int j=0;j<c;j++){
intMalloc[i][j] = 10*i+j;
printf("intMalloc[%2d][%2d]=%02d\n",i,j,intMalloc[i][j]);
}
}
free((void*) intMalloc);
getchar();
return 0;
}
new and new[] are constructor aware, the C memory allocation functions are not.
Similarly, delete and delete [] are destructor aware, whereas free isn't.
realloc does not work with memory allocated with new, there is no standards defined analog to the realloc function with C++ memory management functions.
Do not mix new and delete with malloc/calloc/realloc and free (i.e. don't free any memory allocated with new, don't delete any memory allocated with malloc)
If you are doing new [], you most likely should be using an std::vector, which encapsulates all that memory management for you.
If you are using memory allocated raw pointers, you might be better served using smart/semi-smart pointers like boost::shared_ptr or boost::scoped_ptr or std::auto_ptr, depending on your needs.
Thanks to David Thornley for bringing this up:
Never mix scalar new and delete with their array forms, i.e. don't delete[] memory allocated with new, and don't delete memory allocated with new[]. Undefined behavior all around.
In your example, you SHOULD use new and new[] if you must, because as I said, they are constructor aware, and your class is not a POD data type since it has a constructor.
Please see the C++ FAQ for more information:
C++ FAQ Freestore Management
1) Should I use malloc in c++, or new?
If I use new, can I still use realloc?
Use new. And never use realloc with new.
When should I use realloc? What are
the implications of using it in terms
of performance and bugs?
Instead of using realloc, I usually implement my own memory-pool, from which I reallocate memory when I need it. This also improves performance.
Should I use malloc in c++, or new? If
I use new, can I still use realloc?
You can use malloc in C++; however, it is strongly discouraged in most circumstances. Additionally, if you call malloc, calloc, realloc, etc., you need to use free to deallocate the memory when done.
If you use new to allocate memory, you must use delete to deallocate it.
The C-allocation routines do not have type safety. new does.
If you want to write C++ (!!) programs don't use malloc, realloc, free. It is just not C++ functions.
And there is no necessity to use new is your cases (I'm talking about the example).
You should use vector or some other containter.
In general, you should try to avoid doing your own memory allocation in C++. Most (not all) arrays can be done with std::vector better than you're going to do your own, particularly since you are making a mistake here.
You allocate, say, intNew and intNew[i]. Then you delete [] intNew; (the brackets are necessary here, leaving them off is an error), without delete []ing any of the intNew[i]. The one-dimensional arrays you allocated are now memory leaks, and cannot possibly be freed because you've lost all references to them. Neither C nor C++ normally come with a garbage collector.
The C memory allocation functions deal with memory only. They aren't type-safe, and don't call constructors or destructors. They can be used with data types that require neither, but you do have to make sure they do neither. (It is possible to malloc memory and use placement new to create objects there, but that's more advanced.)
The C++ memory allocation functions deal with memory and objects. They are type-safe, mostly, and do call constructors and destructors. Not all objects can be moved safely, so there is no equivalent of malloc. The tricky part is that you have to match new with delete, and new[] with delete[]. You have this error in your code: delete intNew; should be delete [] intNew;.