[libfann] 49/242: changed fann_..._error to fann_..._MSE and write error output if structures are not allocated correctly. Also make sure that stuff are deallocated correctly in case of error
Christian Kastner
chrisk-guest at moszumanska.debian.org
Sat Oct 4 21:10:19 UTC 2014
This is an automated email from the git hooks/post-receive script.
chrisk-guest pushed a commit to tag Version2_0_0
in repository libfann.
commit ba9df086a8fe2b4a7ed0745ea71b56d2cf02ad20
Author: Steffen Nissen <lukesky at diku.dk>
Date: Tue Jan 13 09:16:39 2004 +0000
changed fann_..._error to fann_..._MSE and write error output if structures are not allocated correctly. Also make sure that stuff are deallocated correctly in case of error
---
TODO | 4 +-
src/fann.c | 130 +++++++++++++++++++++++++++++++++++++-------
src/fann_internal.c | 36 +++++++++++-
src/include/fann.h | 10 ++++
src/include/fann_internal.h | 1 +
5 files changed, 156 insertions(+), 25 deletions(-)
diff --git a/TODO b/TODO
index 73b6bdd..65cc5e7 100644
--- a/TODO
+++ b/TODO
@@ -1,10 +1,8 @@
* Implement quickprop training
* Implement rprop training.
* More advanced activation functions.
-* Check to see if memory is allocated correct.
-* More advanced error printing.
* More checks to see if train data is properly formatted in the file (some have experienced nasty problems because a number was missing in one line).
-* Good reference manual.
* DEB packaging.
* Make it easy to use in windows compilers as Borland C++ and MS Visual C++.
+* Good reference manual.
* Convert existing comments to doxygen-friendly comments.
diff --git a/src/fann.c b/src/fann.c
index 05623a0..bed3c46 100644
--- a/src/fann.c
+++ b/src/fann.c
@@ -54,6 +54,10 @@ struct fann * fann_create_array(float connection_rate, float learning_rate, unsi
/* allocate the general structure */
ann = fann_allocate_structure(learning_rate, num_layers);
+ if(ann == NULL){
+ return NULL;
+ }
+
ann->connection_rate = connection_rate;
#ifdef FIXEDFANN
decimal_point = ann->decimal_point;
@@ -76,6 +80,10 @@ struct fann * fann_create_array(float connection_rate, float learning_rate, unsi
/* allocate room for the actual neurons */
fann_allocate_neurons(ann);
+ if(ann->errno_f == FANN_E_CANT_ALLOCATE_MEM){
+ fann_destroy(ann);
+ return NULL;
+ }
#ifdef DEBUG
printf("creating network with learning rate %f and connection rate %f\n", learning_rate, connection_rate);
@@ -115,6 +123,10 @@ struct fann * fann_create_array(float connection_rate, float learning_rate, unsi
}
fann_allocate_connections(ann);
+ if(ann->errno_f == FANN_E_CANT_ALLOCATE_MEM){
+ fann_destroy(ann);
+ return NULL;
+ }
if(connection_rate == 1){
prev_layer_size = ann->num_input+1;
@@ -293,6 +305,7 @@ struct fann * fann_create_from_file(const char *configuration_file)
/* compares the version information */
if(strncmp(read_version, FANN_CONF_VERSION"\n", strlen(FANN_CONF_VERSION"\n")) != 0){
fann_error(NULL, FANN_E_WRONG_CONFIG_VERSION, configuration_file);
+ free(read_version);
return NULL;
}
@@ -312,6 +325,9 @@ struct fann * fann_create_from_file(const char *configuration_file)
}
ann = fann_allocate_structure(learning_rate, num_layers);
+ if(ann == NULL){
+ return NULL;
+ }
ann->connection_rate = connection_rate;
#ifdef FIXEDFANN
@@ -334,7 +350,8 @@ struct fann * fann_create_from_file(const char *configuration_file)
for(layer_it = ann->first_layer; layer_it != ann->last_layer; layer_it++){
if(fscanf(conf, "%u ", &layer_size) != 1){
fann_error(ann, FANN_E_CANT_READ_NEURON, configuration_file);
- return ann;
+ fann_destroy(ann);
+ return NULL;
}
/* we do not allocate room here, but we make sure that
last_neuron - first_neuron is the number of neurons */
@@ -351,18 +368,27 @@ struct fann * fann_create_from_file(const char *configuration_file)
/* allocate room for the actual neurons */
fann_allocate_neurons(ann);
+ if(ann->errno_f == FANN_E_CANT_ALLOCATE_MEM){
+ fann_destroy(ann);
+ return NULL;
+ }
last_neuron = (ann->last_layer-1)->last_neuron;
for(neuron_it = ann->first_layer->first_neuron;
neuron_it != last_neuron; neuron_it++){
if(fscanf(conf, "%u ", &neuron_it->num_connections) != 1){
fann_error(ann, FANN_E_CANT_READ_NEURON, configuration_file);
- return ann;
+ fann_destroy(ann);
+ return NULL;
}
ann->total_connections += neuron_it->num_connections;
}
fann_allocate_connections(ann);
+ if(ann->errno_f == FANN_E_CANT_ALLOCATE_MEM){
+ fann_destroy(ann);
+ return NULL;
+ }
connected_neurons = (ann->first_layer+1)->first_neuron->connected_neurons;
weights = (ann->first_layer+1)->first_neuron->weights;
@@ -371,7 +397,8 @@ struct fann * fann_create_from_file(const char *configuration_file)
for(i = 0; i < ann->total_connections; i++){
if(fscanf(conf, "(%u "FANNSCANF") ", &input_neuron, &weights[i]) != 2){
fann_error(ann, FANN_E_CANT_READ_CONNECTIONS, configuration_file);
- return ann;
+ fann_destroy(ann);
+ return NULL;
}
connected_neurons[i] = first_neuron+input_neuron;
}
@@ -388,14 +415,14 @@ struct fann * fann_create_from_file(const char *configuration_file)
*/
void fann_destroy(struct fann *ann)
{
- free((ann->first_layer+1)->first_neuron->weights);
- free((ann->first_layer+1)->first_neuron->connected_neurons);
- free(ann->first_layer->first_neuron);
- free(ann->first_layer);
- free(ann->output);
- if(ann->train_deltas != NULL) free(ann->train_deltas);
- fann_reset_errstr(ann); /* free ann->errstr if exists */
- free(ann);
+ fann_safe_free((ann->first_layer+1)->first_neuron->weights);
+ fann_safe_free((ann->first_layer+1)->first_neuron->connected_neurons);
+ fann_safe_free(ann->first_layer->first_neuron);
+ fann_safe_free(ann->first_layer);
+ fann_safe_free(ann->output);
+ fann_safe_free(ann->train_deltas);
+ fann_safe_free(ann->errstr);
+ fann_safe_free(ann);
}
/* Save the network.
@@ -522,6 +549,10 @@ void fann_train(struct fann *ann, fann_type *input, fann_type *desired_output)
/* if no room allocated for the delta variabels, allocate it now */
if(ann->train_deltas == NULL){
ann->train_deltas = (fann_type *)calloc(ann->total_neurons, sizeof(fann_type));
+ if(ann->train_deltas == NULL){
+ fann_error(ann, FANN_E_CANT_ALLOCATE_MEM);
+ return;
+ }
}
delta_begin = ann->train_deltas;
@@ -658,15 +689,20 @@ struct fann_train_data* fann_read_train_from_file(char *filename)
FILE *file = fopen(filename, "r");
- data = (struct fann_train_data *)malloc(sizeof(struct fann_train_data));
-
if(!file){
fann_error(NULL, FANN_E_CANT_OPEN_TD_R, filename);
return NULL;
}
+ data = (struct fann_train_data *)malloc(sizeof(struct fann_train_data));
+ if(data == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ return NULL;
+ }
+
if(fscanf(file, "%u %u %u\n", &num_data, &num_input, &num_output) != 3){
fann_error(NULL, FANN_E_CANT_READ_TD, filename, line);
+ fann_destroy_train(data);
return NULL;
}
line++;
@@ -675,22 +711,47 @@ struct fann_train_data* fann_read_train_from_file(char *filename)
data->num_input = num_input;
data->num_output = num_output;
data->input = (fann_type **)calloc(num_data, sizeof(fann_type *));
+ if(data->input == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ fann_destroy_train(data);
+ return NULL;
+ }
+
data->output = (fann_type **)calloc(num_data, sizeof(fann_type *));
+ if(data->output == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ fann_destroy_train(data);
+ return NULL;
+ }
for(i = 0; i != num_data; i++){
data->input[i] = (fann_type *)calloc(num_input, sizeof(fann_type));
+ if(data->input[i] == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ fann_destroy_train(data);
+ return NULL;
+ }
+
for(j = 0; j != num_input; j++){
if(fscanf(file, FANNSCANF" ", &data->input[i][j]) != 1){
fann_error(NULL, FANN_E_CANT_READ_TD, filename, line);
+ fann_destroy_train(data);
return NULL;
}
}
line++;
data->output[i] = (fann_type *)calloc(num_output, sizeof(fann_type));
+ if(data->output[i] == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ fann_destroy_train(data);
+ return NULL;
+ }
+
for(j = 0; j != num_output; j++){
if(fscanf(file, FANNSCANF" ", &data->output[i][j]) != 1){
fann_error(NULL, FANN_E_CANT_READ_TD, filename, line);
+ fann_destroy_train(data);
return NULL;
}
}
@@ -720,13 +781,21 @@ void fann_save_train_to_fixed(struct fann_train_data* data, char *filename, unsi
void fann_destroy_train(struct fann_train_data *data)
{
unsigned int i;
- for(i = 0; i != data->num_data; i++){
- free(data->input[i]);
- free(data->output[i]);
+ if(data->input){
+ for(i = 0; i != data->num_data; i++){
+ fann_safe_free(data->input[i]);
+ }
+ }
+
+ if(data->output){
+ for(i = 0; i != data->num_data; i++){
+ fann_safe_free(data->output[i]);
+ }
}
- free(data->input);
- free(data->output);
- free(data);
+
+ fann_safe_free(data->input);
+ fann_safe_free(data->output);
+ fann_safe_free(data);
}
#ifndef FIXEDFANN
@@ -744,13 +813,13 @@ void fann_train_on_data_callback(struct fann *ann, struct fann_train_data *data,
for(i = 1; i <= max_epochs; i++){
/* train */
- fann_reset_error(ann);
+ fann_reset_MSE(ann);
for(j = 0; j != data->num_data; j++){
fann_train(ann, data->input[j], data->output[j]);
}
- error = fann_get_error(ann);
+ error = fann_get_MSE(ann);
/* print current output */
if(epochs_between_reports &&
@@ -783,6 +852,9 @@ void fann_train_on_data(struct fann *ann, struct fann_train_data *data, unsigned
void fann_train_on_file_callback(struct fann *ann, char *filename, unsigned int max_epochs, unsigned int epochs_between_reports, float desired_error, int (*callback)(unsigned int epochs, float error))
{
struct fann_train_data *data = fann_read_train_from_file(filename);
+ if(data == NULL){
+ return;
+ }
fann_train_on_data_callback(ann, data, max_epochs, epochs_between_reports, desired_error, callback);
fann_destroy_train(data);
}
@@ -796,9 +868,17 @@ void fann_train_on_file(struct fann *ann, char *filename, unsigned int max_epoch
#endif
/* get the mean square error.
+ (obsolete will be removed at some point, use fann_get_MSE)
*/
float fann_get_error(struct fann *ann)
{
+ return fann_get_MSE(ann);
+}
+
+/* get the mean square error.
+ */
+float fann_get_MSE(struct fann *ann)
+{
if(ann->num_errors){
return ann->error_value/(float)ann->num_errors;
}else{
@@ -807,9 +887,17 @@ float fann_get_error(struct fann *ann)
}
/* reset the mean square error.
+ (obsolete will be removed at some point, use fann_reset_MSE)
*/
void fann_reset_error(struct fann *ann)
{
+ fann_reset_MSE(ann);
+}
+
+/* reset the mean square error.
+ */
+void fann_reset_MSE(struct fann *ann)
+{
ann->num_errors = 0;
ann->error_value = 0;
}
diff --git a/src/fann_internal.c b/src/fann_internal.c
index 408e416..1794199 100644
--- a/src/fann_internal.c
+++ b/src/fann_internal.c
@@ -44,6 +44,11 @@ struct fann * fann_allocate_structure(float learning_rate, unsigned int num_laye
/* allocate and initialize the main network structure */
ann = (struct fann *)malloc(sizeof(struct fann));
+ if(ann == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ return NULL;
+ }
+
ann->learning_rate = learning_rate;
ann->total_neurons = 0;
ann->total_connections = 0;
@@ -74,6 +79,12 @@ struct fann * fann_allocate_structure(float learning_rate, unsigned int num_laye
/* allocate room for the layers */
ann->first_layer = (struct fann_layer *)calloc(num_layers, sizeof(struct fann_layer));
+ if(ann->first_layer == NULL){
+ fann_error(NULL, FANN_E_CANT_ALLOCATE_MEM);
+ free(ann);
+ return NULL;
+ }
+
ann->last_layer = ann->first_layer + num_layers;
return ann;
@@ -90,6 +101,10 @@ void fann_allocate_neurons(struct fann *ann)
/* all the neurons is allocated in one long array */
neurons = (struct fann_neuron *)calloc(ann->total_neurons, sizeof(struct fann_neuron));
+ if(neurons == NULL){
+ fann_error(ann, FANN_E_CANT_ALLOCATE_MEM);
+ return;
+ }
/* clear data, primarily to make the input neurons cleared */
memset(neurons, 0, ann->total_neurons * sizeof(struct fann_neuron));
@@ -102,6 +117,10 @@ void fann_allocate_neurons(struct fann *ann)
}
ann->output = (fann_type *)calloc(num_neurons, sizeof(fann_type));
+ if(ann->output == NULL){
+ fann_error(ann, FANN_E_CANT_ALLOCATE_MEM);
+ return;
+ }
}
/* Allocate room for the connections.
@@ -115,11 +134,20 @@ void fann_allocate_connections(struct fann *ann)
unsigned int connections_so_far = 0;
weights = (fann_type *)calloc(ann->total_connections, sizeof(fann_type));
+ if(weights == NULL){
+ fann_error(ann, FANN_E_CANT_ALLOCATE_MEM);
+ return;
+ }
/* TODO make special cases for all places where the connections
is used, so that it is not needed for fully connected networks.
*/
connected_neurons = (struct fann_neuron **) calloc(ann->total_connections, sizeof(struct fann_neuron*));
+ if(connected_neurons == NULL){
+ fann_error(ann, FANN_E_CANT_ALLOCATE_MEM);
+ return;
+ }
+
last_layer = ann->last_layer;
for(layer_it = ann->first_layer+1; layer_it != ann->last_layer; layer_it++){
@@ -133,7 +161,7 @@ void fann_allocate_connections(struct fann *ann)
if(connections_so_far != ann->total_connections){
fann_error(ann, FANN_E_WRONG_NUM_CONNECTIONS, connections_so_far, ann->total_connections);
- exit(0);
+ return;
}
}
@@ -455,10 +483,16 @@ void fann_error(struct fann *ann, const unsigned int errno, ...)
unsigned int flag = 0;
char * errstr;
+ if(ann != NULL) ann->errno_f = errno;
+
if(ann != NULL && ann->errstr != NULL){
errstr = ann->errstr;
}else{
errstr = (char *)malloc(FANN_ERRSTR_MAX);
+ if(errstr == NULL){
+ fprintf(stderr, "Unable to allocate memory.\n");
+ return;
+ }
}
va_start(ap, errno);
diff --git a/src/include/fann.h b/src/include/fann.h
index 754e122..7f559fc 100644
--- a/src/include/fann.h
+++ b/src/include/fann.h
@@ -260,13 +260,23 @@ void fann_save_train(struct fann_train_data* data, char *filename);
void fann_save_train_to_fixed(struct fann_train_data* data, char *filename, unsigned int decimal_point);
/* Reads the mean square error from the network.
+ (obsolete will be removed at some point, use fann_get_MSE)
*/
float fann_get_error(struct fann *ann);
+/* Reads the mean square error from the network.
+ */
+float fann_get_MSE(struct fann *ann);
+
/* Resets the mean square error from the network.
+ (obsolete will be removed at some point, use fann_reset_MSE)
*/
void fann_reset_error(struct fann *ann);
+/* Resets the mean square error from the network.
+ */
+void fann_reset_MSE(struct fann *ann);
+
/* resets the last error number
*/
void fann_reset_errno(struct fann *ann);
diff --git a/src/include/fann_internal.h b/src/include/fann_internal.h
index f27640f..ee40100 100644
--- a/src/include/fann_internal.h
+++ b/src/include/fann_internal.h
@@ -54,6 +54,7 @@ void fann_error(struct fann *ann, unsigned int errno, ...);
/* called fann_max, in order to not interferre with predefined versions of max */
#define fann_max(x, y) (((x) > (y)) ? (x) : (y))
#define fann_min(x, y) (((x) < (y)) ? (x) : (y))
+#define fann_safe_free(x) if(x) free(x)
#define fann_rand(min_value, max_value) (((double)(min_value))+(((double)(max_value)-((double)(min_value)))*rand()/(RAND_MAX+1.0)))
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/libfann.git
More information about the debian-science-commits
mailing list