[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