1

What's the C equivalent (with malloc) of the following

MyClass* ptr = new MyClass(arg1,arg2);

The first thing that comes to my mind is to instantiate a MyClass object on the stack, then do a malloc(sizeof(MyClass)); and then a memcpy(stack, to_malloc'd_memory)

Is there a better way to do it?

Simeon Visser
  • 118,920
  • 18
  • 185
  • 180
Marco A.
  • 43,032
  • 26
  • 132
  • 246
  • There's no class in C - what, apart from malloc, do you want to do? Just initialize the allocated memory via `ptr->... = arg1` – JeffRSon Dec 06 '13 at 11:02
  • typically, just call `calloc()` - this allocates space and sets all the bytes to zero. If you need to specifically set values, then individually set the fields. – Nim Dec 06 '13 at 11:02
  • 2
    Introduce a function `make_my_class` that you can call as `MyClass *ptr = make_my_class(arg1, arg2);` – Fred Foo Dec 06 '13 at 11:03
  • Asked before - http://stackoverflow.com/questions/3774193/constructor-for-structs-in-c Good practice is to make functions similar to constructors (initializers) with name identical to name of structure. – Pavlus Dec 06 '13 at 11:23

5 Answers5

4

The equivalent (or replacement) of a constructor in C is an initializer. You can use such an initializer in the construction of a compound literal (another C speciality) and by that initialize your new object by assignment.

MyClass* ptr = malloc(sizeof *ptr);
*ptr = (MyClass){ .a = 1, .b = 34 };

a convention to do so systematically could be to always have an "init" function

inline
MyClass* MyClass_init(MyClass* ptr, T1 arg1, T2 arg2) {
   if (ptr) {
     *ptr = (MyClass){ .a = arg1, .b = arg2, };
   }
   return ptr;
}

and then to call that at initialization of the pointer

MyClass* ptr = MyClass_init(malloc(sizeof *ptr), arg1,arg2);
Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
  • Which compiler supports this: `*ptr = (MyClass){ .a = 1, .b = 34 };`? Is this standard? – JeffRSon Dec 06 '13 at 11:19
  • 1
    @JeffRSon it's standard C99. – Simple Dec 06 '13 at 11:55
  • Seems like neither VS2012 nor VS2013 supports it. – JeffRSon Dec 06 '13 at 12:20
  • 1
    @JeffRSon, MS refuses to implement newer C standards in their compilers. They are pretty much alone on this nowadays. Just don't use their compilers for C. – Jens Gustedt Dec 06 '13 at 12:21
  • Yes - it seems they are more into C++11 (http://stackoverflow.com/questions/18731707/why-does-c11-not-support-designated-initializer-list-as-c99), although they emphasize C99 library support: http://blogs.msdn.com/b/vcblog/archive/2013/07/19/c99-library-support-in-visual-studio-2013.aspx – JeffRSon Dec 06 '13 at 12:25
2

There is none. You might follow this scheme:

typedef struct NamespaceClassData {
    ...
} NamespaceClass;

NamespaceClass* namespace_class_create(T arg1, U arg2) {
   // malloc and initialize
}

void namespace_class_destroy(MyClass* p) {
   // destroy and free
}

Note: While struct X is a type in C++, it is just a tag in C (hence the typedef struct)

1

This is not easily done, since malloc (or the C language itself) is not aware of something like "constructors".

Note that the following workaround is not safe for anything related to memory management.

MyClass* ptr = malloc(sizeof(MyClass));
*ptr = MyClass(arg1, arg2);
Max Truxa
  • 3,308
  • 25
  • 38
1

Yes, simply put whatever data you need into the malloced memory -- that's what construction is.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
0

this would only work if your class is very simply, and support shallow copy. I didnt write c code for some time now, but what I would do,is create an init function( init () ), that will act like ctor, and create a macro that will allocate the memory (maloc), and then call the init ( ##init() ). something like:

  1 #define NEW(TYPE, NAME) malloc(sizeof(TYPE));\
  2                         init_ ##TYPE(NAME);
yosim
  • 503
  • 2
  • 8