Skip to content

Commit 564379f

Browse files
AnHardtfpistm
authored andcommitted
Fix RAM losses when creating files
File::File used to allocate RAM what was not freed when destroying the File object. Adding a dedicated destructor war not enough to fix. It would also need copy- and move-constructors. Removed the File::FILE(const char* name) constructor. Changed the File::File(void) constructor to not malloc() any RAM. Unified and changed the SDClass::open() methods. Removed the open method without mode parameter. Instead gave the method with a mode parameter a default mode. Now open() has the complete control over memory allocation. When it is not able to open a file no memory in left allocated. Advantage: A created File what was not opened or was not able to be opened has not to be closed anymore to avoid memory losses. Only a scsessfilly opened file has to be closed.
1 parent 9fe9579 commit 564379f

File tree

2 files changed

+30
-65
lines changed

2 files changed

+30
-65
lines changed

src/SD.cpp

Lines changed: 29 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -119,34 +119,43 @@ bool SDClass::rmdir(const char *filepath)
119119
/**
120120
* @brief Open a file on the SD disk, if not existing it's created
121121
* @param filename: File name
122+
* @param mode: the mode in which to open the file
122123
* @retval File object referring to the opened file
123124
*/
124-
File SDClass::open(const char *filepath)
125+
File SDClass::open(const char *filepath, uint8_t mode /* = FA_READ */)
125126
{
126-
File file = File(filepath);
127+
File file = File();
127128

128-
if (f_open(file._fil, filepath, FA_READ) != FR_OK) {
129-
f_opendir(&file._dir, filepath);
129+
file._name = (char *)malloc(strlen(filepath) + 1);
130+
if (file._name == NULL) {
131+
Error_Handler();
130132
}
131-
return file;
132-
}
133+
sprintf(file._name, "%s", filepath);
133134

134-
/**
135-
* @brief Open a file on the SD disk, if not existing it's created
136-
* @param filename: File name
137-
* @param mode: the mode in which to open the file
138-
* @retval File object referring to the opened file
139-
*/
140-
File SDClass::open(const char *filepath, uint8_t mode)
141-
{
142-
File file = File(filepath);
135+
file._fil = (FIL *)malloc(sizeof(FIL));
136+
if (file._fil == NULL) {
137+
Error_Handler();
138+
}
143139

140+
#if _FATFS == 68300
141+
file._fil->obj.fs = 0;
142+
file._dir.obj.fs = 0;
143+
#else
144+
file._fil->fs = 0;
145+
file._dir.fs = 0;
146+
#endif
147+
144148
if ((mode == FILE_WRITE) && (!SD.exists(filepath))) {
145149
mode = mode | FA_CREATE_ALWAYS;
146150
}
147151

148152
if (f_open(file._fil, filepath, mode) != FR_OK) {
149-
f_opendir(&file._dir, filepath);
153+
free(file._fil);
154+
file._fil = NULL;
155+
if (f_opendir(&file._dir, filepath) != FR_OK) {
156+
free(file._name);
157+
file._name = NULL;
158+
}
150159
}
151160
return file;
152161
}
@@ -167,52 +176,13 @@ bool SDClass::remove(const char *filepath)
167176

168177
File SDClass::openRoot(void)
169178
{
170-
File file = File(_fatFs.getRoot());
171-
172-
if (f_opendir(&file._dir, _fatFs.getRoot()) != FR_OK) {
173-
#if _FATFS == 68300
174-
file._dir.obj.fs = 0;
175-
#else
176-
file._dir.fs = 0;
177-
#endif
178-
}
179-
return file;
179+
return open(_fatFs.getRoot());
180180
}
181181

182182
File::File()
183183
{
184184
_name = NULL;
185-
_fil = (FIL *)malloc(sizeof(FIL));
186-
if (_fil == NULL) {
187-
Error_Handler();
188-
}
189-
#if _FATFS == 68300
190-
_fil->obj.fs = 0;
191-
_dir.obj.fs = 0;
192-
#else
193-
_fil->fs = 0;
194-
_dir.fs = 0;
195-
#endif
196-
}
197-
198-
File::File(const char *name)
199-
{
200-
_name = (char *)malloc(strlen(name) + 1);
201-
if (_name == NULL) {
202-
Error_Handler();
203-
}
204-
sprintf(_name, "%s", name);
205-
_fil = (FIL *)malloc(sizeof(FIL));
206-
if (_fil == NULL) {
207-
Error_Handler();
208-
}
209-
#if _FATFS == 68300
210-
_fil->obj.fs = 0;
211-
_dir.obj.fs = 0;
212-
#else
213-
_fil->fs = 0;
214-
_dir.fs = 0;
215-
#endif
185+
_fil = NULL;
216186
}
217187

218188
/** List directory contents to Serial.
@@ -617,9 +587,6 @@ File File::openNextFile(uint8_t mode)
617587
FRESULT res = FR_OK;
618588
FILINFO fno;
619589
char *fn;
620-
char *fullPath = NULL;
621-
size_t name_len = strlen(_name);
622-
size_t len = name_len;
623590
#if _USE_LFN && _FATFS != 68300
624591
static char lfn[_MAX_LFN];
625592
fno.lfname = lfn;
@@ -638,8 +605,8 @@ File File::openNextFile(uint8_t mode)
638605
#else
639606
fn = fno.fname;
640607
#endif
641-
len += strlen(fn) + 2;
642-
fullPath = (char *)malloc(len);
608+
size_t name_len = strlen(_name);
609+
char *fullPath = (char *)malloc(name_len + strlen(fn) + 2);
643610
if (fullPath != NULL) {
644611
// Avoid twice '/'
645612
if ((name_len > 0) && (_name[name_len - 1] == '/')) {

src/STM32SD.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ uint8_t const LS_R = 4;
3333
class File {
3434
public:
3535
File(void);
36-
File(const char *name);
3736
virtual size_t write(uint8_t);
3837
virtual size_t write(const uint8_t *buf, size_t size);
3938
virtual size_t write(const char *buf, size_t size);
@@ -82,8 +81,7 @@ class SDClass {
8281

8382
/* Initialize the SD peripheral */
8483
bool begin(uint32_t detectpin = SD_DETECT_NONE);
85-
static File open(const char *filepath, uint8_t mode);
86-
static File open(const char *filepath);
84+
static File open(const char *filepath, uint8_t mode = FA_READ);
8785
static bool exists(const char *filepath);
8886
static bool mkdir(const char *filepath);
8987
static bool remove(const char *filepath);

0 commit comments

Comments
 (0)