Skip to content

Commit b0249cd

Browse files
authored
Possible Memory Leakage: memmove() and memcpy() are C Functions and are Not Promised in C++ (#3)
* Added Memory.h. (#321) * Bug fixed: unexpected behaviors of `ArrayList`. (#321) * Updated test ArrayList.cpp. (#321) * Matched Python APIs. (#321) * Removed `arraymove()`. (#321) * Code reformatted. (#321) * Exported Memory.h. (#321) * Code reformatted. (#321)
1 parent b247aca commit b0249cd

File tree

13 files changed

+63
-39
lines changed

13 files changed

+63
-39
lines changed

keywords.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Peer KEYWORD1
77
pulseTriggered KEYWORD2
88
returnFloat KEYWORD2
99
returnDouble KEYWORD2
10+
arraycopy KEYWORD2
1011
LEFT_FRONT_WHEEL_SPEED_SENSOR LITERAL1
1112
RIGHT_FRONT_WHEEL_SPEED_SENSOR LITERAL1
1213
CENTER_REAR_WHEEL_SPEED_SENSOR LITERAL1

src/ArrayList.h

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44

55
#include "Arduino.h"
6+
#include "Memory.h"
67

78
template<typename E>
89
class ArrayList {
@@ -14,8 +15,7 @@ class ArrayList {
1415
if (newCapacity < minCapacity)
1516
newCapacity = minCapacity;
1617
E *newArray = new E[newCapacity];
17-
memmove(newArray, _array, _size * sizeof(E));
18-
delete[] _array;
18+
arraycopy(_array, newArray, _size);
1919
_array = newArray;
2020
_capacity = newCapacity;
2121
}
@@ -24,16 +24,12 @@ class ArrayList {
2424
grow(minCapacity);
2525
}
2626
void ensureCapacityInternal(size_t minCapacity) { ensureExplicitCapacity(max(10, minCapacity)); }
27-
void add(E *elements, size_t size) {
28-
ensureCapacityInternal(_size + size);
29-
memcpy(_array + _size, elements, size * sizeof(E));
30-
}
3127

3228
public:
3329
explicit ArrayList(size_t initialCapacity = 10) :
3430
_size(0), _capacity(initialCapacity), _array(new E[initialCapacity]) {}
35-
ArrayList(E const *const initialArray, size_t size) : _size(0), _capacity(size), _array(new E[size]) {
36-
memcpy(_array, initialArray, size * sizeof(E));
31+
ArrayList(E const *const initialArray, size_t size) : _size(size), _capacity(size), _array(new E[size]) {
32+
arraycopy(initialArray, _array, size);
3733
}
3834
ArrayList(const ArrayList<E> &other) : ArrayList(other._array, other._size) {}
3935
~ArrayList() { delete[] _array; }
@@ -42,19 +38,18 @@ class ArrayList {
4238
void set(int index, const E &element) { _array[index] = element; }
4339
E get(int index) { return _array[index]; }
4440
void clear() {
45-
delete[] _array;
4641
_array = new E[0];
4742
_size = _capacity = 0;
4843
}
44+
void add(E const *const elements, size_t size) {
45+
ensureCapacityInternal(_size + size);
46+
arraycopy(elements, _array, size, 0, _size);
47+
_size += size;
48+
}
4949
void add(const E &element) {
5050
ensureCapacityInternal(_size + 1);
5151
_array[_size++] = element;
5252
}
53-
ArrayList<E> add(const ArrayList<E> &other) {
54-
ArrayList<E> result = copy();
55-
result += other;
56-
return result;
57-
}
5853
bool contains(const E &element) { return indexOf(element) >= 0; }
5954
int indexOfInRange(const E &element, int start, int stop) {
6055
for (int i = start; i < stop; i++)
@@ -70,13 +65,18 @@ class ArrayList {
7065
return -1;
7166
}
7267
int lastIndexOf(const E &element) { return lastIndexOfInRange(element, 0, _size); }
73-
ArrayList<E> copy() { return ArrayList<E>(reinterpret_cast<size_t>(this)); }
68+
ArrayList<E> copy() { return ArrayList<E>(*this); }
69+
E operator[](int index) { return get(index); }
7470
ArrayList<E> operator+(const E &element) {
7571
ArrayList<E> result = copy();
7672
result += element;
7773
return result;
7874
}
79-
ArrayList<E> operator+(const ArrayList<E> &other) { return add(other); }
75+
ArrayList<E> operator+(const ArrayList<E> &other) {
76+
ArrayList<E> result = copy();
77+
result += other;
78+
return result;
79+
}
8080
ArrayList<E> &operator+=(const E &element) {
8181
add(element);
8282
return *this;
@@ -88,8 +88,12 @@ class ArrayList {
8888
ArrayList<E> &operator=(const ArrayList<E> &other) {
8989
if (this != &other) {
9090
ensureCapacityInternal(other._capacity);
91-
if (other._size > 0)
92-
memcpy(_array, other._array, _size * sizeof(E));
91+
if (other._size > 0) {
92+
_array = new E[other._capacity];
93+
_capacity = other._capacity;
94+
arraycopy(other._array, _array, other._size);
95+
_size = other._size;
96+
}
9397
}
9498
return *this;
9599
}

src/Controller.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@ class Controller : public Device<T> {
99
protected:
1010
ArrayList<String> _device_tags;
1111
ArrayList<Device<E>> _devices;
12-
void _attachDevice(const String &tag, Device<E> device) {
12+
void _attachDevice(const String &tag, const Device<E> &device) {
1313
_device_tags.add(tag);
1414
_devices.add(device);
1515
device.tag(tag);
1616
}
1717

1818
public:
1919
Controller() : Device<T>() {}
20-
int level() { return this->_parentTags.size(); }
2120
const ArrayList<Device<E>> &devices() { return _devices; }
2221
void device(const String &tag, const Device<E> &device) { _attachDevice(tag, device); }
23-
Device<E> device(const String &tag) { return _devices.get(_device_tags.indexOf(tag)); }
22+
Device<E> device(const String &tag) { return _devices[_device_tags.indexOf(tag)]; }
2423
void initialize(const ArrayList<String> &parentTags) override {
2524
Device<E>::initialize(parentTags);
2625
for (Device<E> d: _devices)

src/Device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class Device {
1515
explicit Device(const ArrayList<int> &pins) : _pins(pins) {}
1616
Device() : Device(ArrayList<int>(0)) {}
1717
~Device() = default;
18+
int level() { return _parentTags.size(); }
1819
void tag(const String &tag) { _tag = tag; }
1920
String tag() { return _tag; }
2021
const ArrayList<String> &parentTags() { return _parentTags; }

src/LEADS.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include "Controller.h"
22
#include "Device.h"
3+
#include "Memory.h"
34
#include "Peer.h"
45
#include "PredefinedTags.h"
56
#include "Utils.h"

src/Memory.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef MEMORY_H
2+
#define MEMORY_H
3+
4+
5+
template<typename E>
6+
void arraycopy(const E *const from, E *to, int size, int fromOffset = 0, int toOffset = 0) {
7+
for (int i = 0; i < size; i++)
8+
to[i + toOffset] = from[i + fromOffset];
9+
}
10+
11+
12+
#endif // MEMORY_H

src/Peer.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
#include "Peer.h"
22

33

4-
Peer::Peer(unsigned int baudRate, String separator, String remainder) :
4+
// std::move() is not available in the C library
5+
Peer::Peer(unsigned int baudRate, const String &separator, const String &remainder) : // NOLINT(*-pass-by-value)
56
Controller<String, String>(), _baudRate(baudRate), _separator(separator), _remainder(remainder) {}
67
void Peer::initialize(const ArrayList<String> &parentTags) {
78
Controller<String, String>::initialize(parentTags);
89
Serial.begin(_baudRate);
910
}
1011
String Peer::read() {
11-
char c = Serial.read();
12+
char c = char(Serial.read());
1213
if (c > 0) {
1314
_remainder += c;
1415
if (!_remainder.endsWith(_separator))

src/Peer.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class Peer : public Controller<String, String> {
1111
String _separator, _remainder;
1212

1313
public:
14-
explicit Peer(unsigned int baudRate = 9600, String separator = ";", String remainder = "");
14+
explicit Peer(unsigned int baudRate = 9600, const String &separator = ";", const String &remainder = "");
1515
void initialize(const ArrayList<String> &parentTags) override;
1616
String read() override;
1717
void write(String payload) override;

src/Utils.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
bool pulseTriggered(int pin) { return digitalRead(pin) == LOW; }
44

5-
void returnFloat(Peer peer, const String &tag, float n) { peer.write(tag + ":" + n); }
5+
void returnFloat(Peer &peer, const String &tag, float n) { peer.write(tag + ":" + n); }
66

7-
void returnDouble(Peer peer, const String &tag, double n) { peer.write(tag + ":" + n); }
7+
void returnDouble(Peer &peer, const String &tag, double n) { peer.write(tag + ":" + n); }

src/Utils.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
bool pulseTriggered(int pin);
99

10-
void returnFloat(Peer peer, const String &tag, float n);
10+
void returnFloat(Peer &peer, const String &tag, float n);
1111

12-
void returnDouble(Peer peer, const String &tag, double n);
12+
void returnDouble(Peer &peer, const String &tag, double n);
1313

1414

1515
#endif // UTILS_H

0 commit comments

Comments
 (0)