Skip to content

Commit 7d5be06

Browse files
committed
fix(explode): allocate the needed size only 🐛
1 parent 73fe49f commit 7d5be06

File tree

4 files changed

+95
-83
lines changed

4 files changed

+95
-83
lines changed

src/explode.c

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -3,62 +3,61 @@
33
//
44

55
#include "include/explode.h"
6+
#include "common.h"
67
#include <stdlib.h>
78

8-
9-
void copy(char* dist, const char* source, size_t length) {
10-
for (int i = 0; i < length; ++i)
11-
{
12-
dist[i] = source[i];
13-
}
9+
void copy(char *dist, const char *source, size_t length) {
10+
for (int i = 0; i < length; ++i) {
11+
dist[i] = source[i];
12+
}
1413
}
1514

16-
explode_s explode_make(const char* text, char character)
17-
{
18-
explode_s e;
19-
20-
e.count = 0;
21-
//temp
22-
e.values = malloc(sizeof(char*) * 50);
23-
24-
const char* textPointer = text;
25-
const char* chunkStart = text;
26-
size_t i = 0;
27-
28-
while (*textPointer != '\0')
29-
{
30-
if (*textPointer == character)
31-
{
32-
size_t chunkLength = textPointer - chunkStart;
33-
e.values[i] = malloc(chunkLength + 1);
34-
copy(e.values[i], chunkStart, chunkLength);
35-
e.values[i][chunkLength] = 0;
36-
chunkStart = textPointer + 1;
37-
e.count++;
38-
i++;
39-
}
40-
textPointer++;
41-
}
15+
char **_extend_values(char **values_pointer, size_t size) {
16+
// if (values_pointer == NULL) {
17+
// return malloc(values_pointer);
18+
// }
19+
return realloc(values_pointer, sizeof(char *) * size);
20+
}
4221

43-
if (i > 0) {
44-
size_t chunkLength = textPointer - chunkStart;
45-
e.values[i] = malloc(chunkLength + 1);
46-
copy(e.values[i], chunkStart, chunkLength);
47-
e.values[i][chunkLength] = 0;
48-
e.count++;
22+
explode_s explode_make(const char *text, char character) {
23+
explode_s e = {0};
24+
25+
e.count = 0;
26+
27+
const char *textPointer = text;
28+
const char *chunkStart = text;
29+
size_t i = 0;
30+
31+
while (*textPointer != '\0') {
32+
if (*textPointer == character) {
33+
size_t chunkLength = textPointer - chunkStart;
34+
char *spaceForOccurance = malloc(NSIZE(chunkLength));
35+
e.values = _extend_values(e.values, e.count + 1);
36+
e.values[i] = spaceForOccurance;
37+
copy(e.values[i], chunkStart, chunkLength);
38+
e.values[i][chunkLength] = 0;
39+
chunkStart = textPointer + 1;
40+
e.count++;
41+
i++;
4942
}
50-
51-
52-
53-
return e;
43+
textPointer++;
44+
}
45+
46+
if (i > 0) {
47+
size_t chunkLength = textPointer - chunkStart;
48+
e.values = _extend_values(e.values, e.count + 1);
49+
e.values[i] = malloc(NSIZE(chunkLength));
50+
copy(e.values[i], chunkStart, chunkLength);
51+
e.values[i][chunkLength] = 0;
52+
e.count++;
53+
}
54+
55+
return e;
5456
}
5557

56-
57-
void explode_clean(explode_s* exp)
58-
{
59-
for (int i = 0; i < exp->count; ++i)
60-
{
61-
free(exp->values[i]);
62-
}
63-
free(exp->values);
58+
void explode_clean(explode_s *exp) {
59+
for (int i = 0; i < exp->count; ++i) {
60+
free(exp->values[i]);
61+
}
62+
free(exp->values);
6463
}

src/include/common.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
#ifndef COMMON_H
22
#define COMMON_H
3-
#include <stddef.h>
43
#include <stdbool.h>
4+
#include <stddef.h>
55
#include <stdint.h>
66

7+
#define NSIZE(s) (s + 1)
8+
79
#if defined(__cplusplus)
8-
#define BEGIN_DECL extern "C" {
9-
#define END_DECL }
10+
#define BEGIN_DECL extern "C" {
11+
#define END_DECL }
1012
#else
1113
#define BEGIN_DECL
1214
#define END_DECL
1315
#endif
1416

15-
#endif //COMMON_H
17+
#endif // COMMON_H

src/include/explode.h

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@
77

88
#include "common.h"
99

10-
typedef struct
11-
{
12-
char** values;
13-
size_t count;
10+
typedef struct {
11+
char **values;
12+
size_t count;
1413
} explode_s;
1514

16-
1715
BEGIN_DECL
1816

19-
explode_s explode_make(const char* text, char character);
20-
void explode_clean(explode_s* exp);
17+
explode_s explode_make(const char *text, char character);
18+
void explode_clean(explode_s *exp);
2119

2220
END_DECL
2321

24-
#endif //EXPLODE_H
22+
#endif // EXPLODE_H

tests/explode.test.cpp

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,40 @@
55
#include <catch2/catch.hpp>
66
#include <explode.h>
77

8-
TEST_CASE("explode")
9-
{
10-
SECTION("should returns ->count of exploded elements")
11-
{
12-
auto r = explode_make("Hello-World", '-');
13-
REQUIRE(r.count == 2);
14-
explode_clean(&r);
15-
}
8+
using Catch::Matchers::Equals;
169

17-
SECTION("should returns ->count as 0 when character is not found")
18-
{
19-
auto r = explode_make("Hello-World", '*');
20-
REQUIRE(r.count == 0);
21-
explode_clean(&r);
22-
}
10+
TEST_CASE("explode") {
11+
SECTION("should returns ->count of exploded elements") {
12+
auto r = explode_make("Hello-World", '-');
13+
REQUIRE(r.count == 2);
14+
explode_clean(&r);
15+
}
2316

24-
SECTION("should returns ->values as char** for each value between the character")
25-
{
26-
auto r = explode_make("Hello-World", '-');
27-
REQUIRE_THAT(r.values[0], Catch::Equals("Hello"));
28-
REQUIRE_THAT(r.values[1], Catch::Equals("World"));
29-
explode_clean(&r);
30-
}
17+
SECTION("should returns ->values with all content") {
18+
auto r = explode_make("This is a text for a test", ' ');
19+
REQUIRE(r.count == 7);
20+
REQUIRE_THAT(r.values[0], Equals("This"));
21+
REQUIRE_THAT(r.values[1], Equals("is"));
22+
REQUIRE_THAT(r.values[2], Equals("a"));
23+
REQUIRE_THAT(r.values[3], Equals("text"));
24+
REQUIRE_THAT(r.values[4], Equals("for"));
25+
REQUIRE_THAT(r.values[5], Equals("a"));
26+
REQUIRE_THAT(r.values[6], Equals("test"));
27+
REQUIRE(r.values[7] == NULL);
28+
explode_clean(&r);
29+
}
30+
31+
SECTION("should returns ->count as 0 when character is not found") {
32+
auto r = explode_make("Hello-World", '*');
33+
REQUIRE(r.count == 0);
34+
explode_clean(&r);
35+
}
36+
37+
SECTION("should returns ->values as char** for each value between the "
38+
"character") {
39+
auto r = explode_make("Hello-World", '-');
40+
REQUIRE_THAT(r.values[0], Catch::Equals("Hello"));
41+
REQUIRE_THAT(r.values[1], Catch::Equals("World"));
42+
explode_clean(&r);
43+
}
3144
}

0 commit comments

Comments
 (0)