summaryrefslogtreecommitdiffhomepage
path: root/sptr.c
blob: c275b8a0f0fe05487da27262dad782e4a7fc2436 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>

union sptr_u {
	uint8_t base[1];
	uint32_t offset;
};
typedef union sptr_u sptr_t;

struct s {
	uint8_t name1_len;
	uint8_t name2_len;
	uint8_t name3_len;

	sptr_t name1;
	sptr_t name2;
	sptr_t name3;
};

static void sptr_set(sptr_t *sptr, void *ptr)
{
	sptr->offset = (uint8_t *)ptr - sptr->base;

	printf("sptr->base   : %p\n", sptr->base);
	printf("sptr->offset : %u\n", sptr->offset);
}

static void *sptr_get(sptr_t *sptr)
{
	return sptr->base + sptr->offset;
}

int main(void)
{
	static const char * const names[] = { "toor", "foobar", "baz" };
	struct s *s = malloc(sizeof(struct s) +
		             strlen(names[0]) + strlen(names[1]) +
			     strlen(names[2]) + 3);
	char *p = (char *)(s) + sizeof(struct s);

	printf("s : %p\n", s);

	s->name1_len = strlen(names[0]);
	sptr_set(&s->name1, p);
	p = stpcpy(p, names[0]);

	p++;
	s->name2_len = strlen(names[1]);
	sptr_set(&s->name2, p);
	p = stpcpy(p, names[1]);

	p++;
	s->name3_len = strlen(names[2]);
	sptr_set(&s->name3, p);
	p = stpcpy(p, names[2]);

	printf("name1 : %s\n", (const char *)sptr_get(&s->name1));
	printf("name2 : %s\n", (const char *)sptr_get(&s->name2));
	printf("name3 : %s\n", (const char *)sptr_get(&s->name3));

	free(s);

	exit(EXIT_SUCCESS);
}