blob: d63be06a9bbbfc0683ae7e8aec68577692df708a (
plain)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
/* { dg-additional-options "-fanalyzer-call-summaries" } */
typedef __SIZE_TYPE__ size_t;
#define NULL ((void *)0)
/* data structures */
struct screen_s {
size_t rows;
size_t cols;
char **data;
};
struct context_s {
struct screen_s *scr;
};
/* global context variable */
static struct context_s *ctx;
/* prototypes */
struct screen_s *screen_create(size_t cols, size_t rows);
void screen_destroy(struct screen_s *scr);
void resize_screen(size_t cols, size_t rows);
/* functions */
struct screen_s *screen_create(size_t cols, size_t rows)
{
struct screen_s *result = NULL;
result = __builtin_calloc(1, sizeof(*result));
if (!result)
return NULL;
result->cols = cols;
result->rows = rows;
/* make one allocation which will be accessed like a 2D array */
result->data = __builtin_calloc(rows, sizeof(result->data) + sizeof(*result->data) * cols);
if (!result->data) {
__builtin_free(result);
return NULL;
}
/* obtain pointer to start of data area */
char *ptr = (char *)(result->data + rows);
/* setup pointers for each row of data to allow 2D array access */
for (size_t row = 0; row < rows; row++)
result->data[row] = (ptr + row * cols);
/* array can now be accessed like data[row][col] */
return result;
}
void screen_destroy(struct screen_s *scr)
{
if (!scr)
return;
__builtin_free(scr->data);
scr->data = NULL;
scr->rows = 0;
scr->cols = 0;
__builtin_free(scr);
}
void resize_screen(size_t cols, size_t rows)
{
/* create a new screen */
struct screen_s *new_scr = NULL;
new_scr = screen_create(cols, rows); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */
if (!new_scr) {
return;
}
/* swap the old screen with the new one */
struct screen_s *old_scr = ctx->scr;
ctx->scr = new_scr;
/* omitted: copy the old screen contents to the new screen */
/* free the old screen */
screen_destroy(old_scr);
}
int main(void)
{
ctx = __builtin_calloc(1, sizeof(*ctx));
if (!ctx)
__builtin_abort();
ctx->scr = screen_create(80, 25); /* { dg-bogus "leak" "PR 108045" { xfail *-*-* } } */
resize_screen(100, 20);
/* tidy up and quit */
screen_destroy(ctx->scr);
__builtin_free(ctx);
ctx = NULL;
return 0;
}
|