Skip to content

Commit 18e3ea6

Browse files
committed
feat: [structs] Add single malloc struct init
1 parent 4b36bfb commit 18e3ea6

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

cpp/structs/single-malloc.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
/**
2+
* Initialization of struct members with single malloc
3+
* ===================================================
4+
*/
5+
6+
#include "tests.h"
7+
8+
/* ===========================================================================
9+
* Algorithms implementation
10+
* ===========================================================================
11+
*/
12+
typedef struct employee_ {
13+
char *name;
14+
int id;
15+
} ee_t;
16+
17+
/*
18+
* When a struct has pointers e.g. name in struct employee_ then it requires
19+
* at least two malloc calls to allocate memory first for the struct and then
20+
* for its pointer members. This can be a performance issue as malloc calls
21+
* are expensive. To overcome that we allocate a single large block of memory
22+
* with single malloc call and point struct pointer members to locations in
23+
* that block.
24+
*
25+
* p0 is start of pointer to single large block of memory allocated using a
26+
* single malloc. In this block struct pointer members can be pointed to at:
27+
*
28+
* +-------------------+------------------+
29+
* | struct employee_ | remaining memory |
30+
* +-------------+-----+------------------+
31+
* | p0 (id, name_ptr) | p1 (name_val) |
32+
* +-------------------+------------------+
33+
*/
34+
ee_t *init_ee(int id, const char *name)
35+
{
36+
size_t n0 = strlen(name), n1 = n0 + 1;
37+
size_t sz = sizeof(ee_t), es = sz + n1;
38+
39+
char *p0 = (char *)malloc(es);
40+
char *p1 = (char *)(p0 + sz);
41+
42+
memset(p1, 0, n1);
43+
strncpy(p1, name, n0);
44+
45+
ee_t *ep = (ee_t *)p0;
46+
ep->name = p1;
47+
ep->id = id;
48+
return ep;
49+
}
50+
51+
/* ===========================================================================
52+
* Test code
53+
* ===========================================================================
54+
*/
55+
#define _sm_check(_id, _name) \
56+
{ \
57+
ee_t *ep = init_ee(_id, _name); \
58+
string em, am; \
59+
em = format("id: {}, name: {}", _id, _name); \
60+
am = format("id: {}, name: {}", ep->id, ep->name); \
61+
CHECK_EQ(em, am); \
62+
SHOW_OUTPUT(em, am); \
63+
free(ep); \
64+
}
65+
66+
TEST(init_ee, "Initialization of struct members with single malloc")
67+
{
68+
int _i[] = {2, 5};
69+
const char *_n[] = {"abc", "new hello world, testing single malloc"};
70+
int n = sizeof(_i) / sizeof(_i[0]);
71+
fii (i, n) _sm_check(_i[i], _n[i]);
72+
}
73+
74+
INIT_TEST_MAIN();

0 commit comments

Comments
 (0)