Skip to content

Commit 1409e01

Browse files
larsmansFabian Pedregosa
authored andcommitted
Cleanup lib{linear,svm} C helper routines
* Plumb memory leaks in allocation * Don't cast return value from malloc * Remove unused variables * No more register keyword; is a no-op in modern compilers * Cosmetic changes
1 parent b43b502 commit 1409e01

File tree

3 files changed

+151
-55
lines changed

3 files changed

+151
-55
lines changed

scikits/learn/svm/src/liblinear/liblinear_helper.c

Lines changed: 57 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,18 @@
1818
struct feature_node **dense_to_sparse (double *x, npy_intp *dims, double bias)
1919
{
2020
struct feature_node **sparse;
21-
register int i, j; /* number of nonzero elements in row i */
21+
int i, j; /* number of nonzero elements in row i */
2222
struct feature_node *temp; /* stack for nonzero elements */
2323
struct feature_node *T; /* pointer to the top of the stack */
2424
int count;
2525

26-
sparse = (struct feature_node **) malloc (dims[0] * sizeof(struct feature_node *));
27-
temp = (struct feature_node *) malloc ((dims[1]+2) * sizeof(struct feature_node));
26+
sparse = malloc (dims[0] * sizeof(struct feature_node *));
27+
if (sparse == NULL)
28+
goto sparse_error;
2829

29-
if (sparse == NULL || temp == NULL) return NULL;
30+
temp = malloc ((dims[1]+2) * sizeof(struct feature_node));
31+
if (temp == NULL)
32+
goto temp_error;
3033

3134
for (i=0; i<dims[0]; ++i) {
3235
T = temp; /* reset stack pointer */
@@ -53,13 +56,25 @@ struct feature_node **dense_to_sparse (double *x, npy_intp *dims, double bias)
5356

5457
/* allocate memory and copy collected items*/
5558
count = T - temp;
56-
sparse[i] = (struct feature_node *) malloc(count * sizeof(struct feature_node));
57-
if (sparse[i] == NULL) return NULL;
59+
sparse[i] = malloc(count * sizeof(struct feature_node));
60+
if (sparse[i] == NULL) {
61+
int k;
62+
for (k=0; k<i; k++)
63+
free(sparse[i]);
64+
goto sparse_i_error;
65+
}
5866
memcpy(sparse[i], temp, count * sizeof(struct feature_node));
5967
}
6068

6169
free(temp);
6270
return sparse;
71+
72+
sparse_i_error:
73+
free(temp);
74+
temp_error:
75+
free(sparse);
76+
sparse_error:
77+
return NULL;
6378
}
6479

6580

@@ -72,11 +87,22 @@ struct feature_node **csr_to_sparse (double *values, npy_intp *shape_indices,
7287
{
7388
struct feature_node **sparse, *temp;
7489
int i, j=0, k=0, n;
75-
sparse = (struct feature_node **) malloc ((shape_indptr[0]-1)* sizeof(struct feature_node *));
90+
91+
sparse = malloc ((shape_indptr[0]-1)* sizeof(struct feature_node *));
92+
if (sparse == NULL)
93+
return NULL;
7694

7795
for (i=0; i<shape_indptr[0]-1; ++i) {
7896
n = indptr[i+1] - indptr[i]; /* count elements in row i */
79-
sparse[i] = (struct feature_node *) malloc ((n+2) * sizeof(struct feature_node));
97+
98+
sparse[i] = malloc ((n+2) * sizeof(struct feature_node));
99+
if (sparse[i] == NULL) {
100+
int l;
101+
for (l=0; l<i; l++)
102+
free(sparse[i]);
103+
break;
104+
}
105+
80106
temp = sparse[i];
81107
for (j=0; j<n; ++j) {
82108
temp[j].value = values[k];
@@ -101,7 +127,7 @@ struct problem * set_problem(char *X,char *Y, npy_intp *dims, double bias)
101127
{
102128
struct problem *problem;
103129
/* not performant but simple */
104-
problem = (struct problem *) malloc(sizeof(struct problem));
130+
problem = malloc(sizeof(struct problem));
105131
if (problem == NULL) return NULL;
106132
problem->l = (int) dims[0];
107133

@@ -127,7 +153,7 @@ struct problem * csr_set_problem (char *values, npy_intp *n_indices,
127153
npy_intp n_features, double bias) {
128154

129155
struct problem *problem;
130-
problem = (struct problem *) malloc (sizeof (struct problem));
156+
problem = malloc (sizeof (struct problem));
131157
if (problem == NULL) return NULL;
132158
problem->l = (int) n_indptr[0] -1;
133159

@@ -155,7 +181,7 @@ struct problem * csr_set_problem (char *values, npy_intp *n_indices,
155181
struct parameter * set_parameter(int solver_type, double eps, double C, npy_intp nr_weight, char *weight_label, char *weight)
156182
{
157183
struct parameter *param;
158-
param = (struct parameter *) malloc(sizeof(struct parameter));
184+
param = malloc(sizeof(struct parameter));
159185
if (param == NULL) return NULL;
160186
param->solver_type = solver_type;
161187
param->eps = eps;
@@ -174,9 +200,12 @@ struct model * set_model(struct parameter *param, char *coef, npy_intp *dims,
174200
struct model *model;
175201

176202
if (m == 1) m = 2; /* liblinear collapses the weight vector in the case of two classes */
177-
model = (struct model *) malloc(sizeof(struct model));
178-
model->w = (double *) malloc( len_w * sizeof(double));
179-
model->label = (int *) malloc( m * sizeof(int));
203+
if ((model = malloc(sizeof(struct model))) == NULL)
204+
goto model_error;
205+
if ((model->w = malloc( len_w * sizeof(double))) == NULL)
206+
goto w_error;
207+
if ((model->label = malloc( m * sizeof(int))) == NULL)
208+
goto label_error;
180209

181210
memcpy(model->label, label, m * sizeof(int));
182211
memcpy(model->w, coef, len_w * sizeof(double));
@@ -188,6 +217,13 @@ struct model * set_model(struct parameter *param, char *coef, npy_intp *dims,
188217
model->bias = bias;
189218

190219
return model;
220+
221+
label_error:
222+
free(model->w);
223+
w_error:
224+
free(model);
225+
model_error:
226+
return NULL;
191227
}
192228

193229

@@ -218,7 +254,7 @@ int copy_predict(char *train, struct model *model_, npy_intp *train_dims,
218254
char *dec_values)
219255
{
220256
int *t = (int *) dec_values;
221-
register int i, n;
257+
int i, n;
222258
struct feature_node **train_nodes;
223259
n = train_dims[0];
224260
train_nodes = dense_to_sparse((double *) train, train_dims, model_->bias);
@@ -238,7 +274,8 @@ int copy_predict(char *train, struct model *model_, npy_intp *train_dims,
238274
int csr_copy_predict(npy_intp n_features, npy_intp *data_size, char *data,
239275
npy_intp *index_size,
240276
char *index, npy_intp *indptr_shape, char *intptr, struct model *model_,
241-
char *dec_values) {
277+
char *dec_values)
278+
{
242279
int *t = (int *) dec_values;
243280
struct feature_node **predict_nodes;
244281
npy_intp i;
@@ -279,9 +316,8 @@ int csr_copy_predict_values(npy_intp n_features, npy_intp *data_size,
279316
char *data, npy_intp *index_size, char
280317
*index, npy_intp *indptr_shape, char
281318
*intptr, struct model *model_, char
282-
*dec_values, int nr_class) {
283-
284-
int *t = (int *) dec_values;
319+
*dec_values, int nr_class)
320+
{
285321
struct feature_node **predict_nodes;
286322
npy_intp i;
287323

@@ -304,7 +340,7 @@ int copy_prob_predict(char *predict, struct model *model_, npy_intp *predict_dim
304340
char *dec_values)
305341
{
306342
struct feature_node **predict_nodes;
307-
register int i;
343+
int i;
308344
int n, m;
309345
n = predict_dims[0];
310346
m = model_->nr_class;
@@ -328,8 +364,7 @@ int csr_copy_predict_proba(npy_intp n_features, npy_intp *data_size,
328364
char *dec_values)
329365
{
330366
struct feature_node **predict_nodes;
331-
register int i;
332-
double temp;
367+
int i;
333368
double *tx = (double *) dec_values;
334369

335370
predict_nodes = csr_to_sparse((double *) data, index_size,

scikits/learn/svm/src/libsvm/libsvm_helper.c

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ struct svm_node *dense_to_libsvm (double *x, npy_intp *dims)
3737
double *tx = x;
3838
int i;
3939

40-
node = (struct svm_node *) malloc (dims[0] * sizeof(struct svm_node));
40+
node = malloc (dims[0] * sizeof(struct svm_node));
4141

4242
if (node == NULL) return NULL;
4343
for (i=0; i<dims[0]; ++i) {
@@ -53,7 +53,7 @@ struct svm_node *dense_to_libsvm (double *x, npy_intp *dims)
5353

5454

5555
/*
56-
* Create a svm_paramater struct and return it. It is up to the user to
56+
* Create a svm_parameter struct and return it. It is up to the user to
5757
* free the resulting object.
5858
*/
5959
struct svm_parameter * set_parameter(int svm_type, int kernel_type, int degree,
@@ -62,7 +62,7 @@ struct svm_parameter * set_parameter(int svm_type, int kernel_type, int degree,
6262
char *weight_label, char *weight)
6363
{
6464
struct svm_parameter *param;
65-
param = (struct svm_parameter *) malloc(sizeof(struct svm_parameter));
65+
param = malloc(sizeof(struct svm_parameter));
6666
if (param == NULL) return NULL;
6767
param->svm_type = svm_type;
6868
param->kernel_type = kernel_type;
@@ -89,9 +89,8 @@ struct svm_parameter * set_parameter(int svm_type, int kernel_type, int degree,
8989
struct svm_problem * set_problem(char *X, char *Y, char *sample_weight, npy_intp *dims, int kernel_type)
9090
{
9191
struct svm_problem *problem;
92-
int i;
9392

94-
problem = (struct svm_problem *) malloc(sizeof(struct svm_problem));
93+
problem = malloc(sizeof(struct svm_problem));
9594
if (problem == NULL) return NULL;
9695
problem->l = (int) dims[0]; /* number of samples */
9796
problem->y = (double *) Y;
@@ -131,18 +130,24 @@ struct svm_model *set_model(struct svm_parameter *param, int nr_class,
131130

132131
m = nr_class * (nr_class-1)/2;
133132

134-
model = (struct svm_model *) malloc(sizeof(struct svm_model));
135-
model->nSV = (int *) malloc(nr_class * sizeof(int));
136-
model->label = (int *) malloc(nr_class * sizeof(int));;
137-
model->sv_coef = (double **) malloc((nr_class-1)*sizeof(double *));
138-
model->rho = (double *) malloc( m * sizeof(double));
133+
if ((model = malloc(sizeof(struct svm_model))) == NULL)
134+
goto model_error;
135+
if ((model->nSV = malloc(nr_class * sizeof(int))) == NULL)
136+
goto nsv_error;
137+
if ((model->label = malloc(nr_class * sizeof(int))) == NULL)
138+
goto label_error;
139+
if ((model->sv_coef = malloc((nr_class-1)*sizeof(double *))) == NULL)
140+
goto sv_coef_error;
141+
if ((model->rho = malloc( m * sizeof(double))) == NULL)
142+
goto rho_error;
139143

140144
model->nr_class = nr_class;
141145
model->param = *param;
142146
model->l = (int) support_dims[0];
143147

144148
if (param->kernel_type == PRECOMPUTED) {
145-
model->SV = (struct svm_node *) malloc ((model->l) * sizeof(struct svm_node));
149+
if ((model->SV = malloc ((model->l) * sizeof(struct svm_node))) == NULL)
150+
goto SV_error;
146151
for (i=0; i<model->l; ++i) {
147152
model->SV[i].ind = ((int *) support)[i];
148153
model->SV[i].values = NULL;
@@ -173,9 +178,11 @@ struct svm_model *set_model(struct svm_parameter *param, int nr_class,
173178
*/
174179

175180
if (param->probability) {
176-
model->probA = (double *) malloc(m * sizeof(double));
181+
if ((model->probA = malloc(m * sizeof(double))) == NULL)
182+
goto probA_error;
177183
memcpy(model->probA, probA, m * sizeof(double));
178-
model->probB = (double *) malloc(m * sizeof(double));
184+
if ((model->probB = malloc(m * sizeof(double))) == NULL)
185+
goto probB_error;
179186
memcpy(model->probB, probB, m * sizeof(double));
180187
} else {
181188
model->probA = NULL;
@@ -185,6 +192,23 @@ struct svm_model *set_model(struct svm_parameter *param, int nr_class,
185192
/* We'll free SV ourselves */
186193
model->free_sv = 0;
187194
return model;
195+
196+
probB_error:
197+
free(model->probA);
198+
probA_error:
199+
free(model->SV);
200+
SV_error:
201+
free(model->rho);
202+
rho_error:
203+
free(model->sv_coef);
204+
sv_coef_error:
205+
free(model->label);
206+
label_error:
207+
free(model->nSV);
208+
nsv_error:
209+
free(model);
210+
model_error:
211+
return NULL;
188212
}
189213

190214

@@ -241,7 +265,7 @@ void copy_intercept(char *data, struct svm_model *model, npy_intp *dims)
241265
*/
242266
void copy_SV(char *data, struct svm_model *model, npy_intp *dims)
243267
{
244-
int i, j, k, n = model->l;
268+
int i, n = model->l;
245269
double *tdata = (double *) data;
246270
int dim = model->SV[0].dim;
247271
for (i=0; i<n; ++i) {
@@ -250,9 +274,9 @@ void copy_SV(char *data, struct svm_model *model, npy_intp *dims)
250274
}
251275
}
252276

253-
int copy_support (char *data, struct svm_model *model)
277+
void copy_support (char *data, struct svm_model *model)
254278
{
255-
memcpy (data, model->sv_ind, (model->l) * sizeof(int));
279+
memcpy (data, model->sv_ind, (model->l) * sizeof(int));
256280
}
257281

258282
/*
@@ -354,7 +378,6 @@ int copy_predict_proba(char *predict, struct svm_model *model, npy_intp *predict
354378
*/
355379
int free_problem(struct svm_problem *problem)
356380
{
357-
register int i;
358381
if (problem == NULL) return -1;
359382
free (problem->x);
360383
free (problem);

0 commit comments

Comments
 (0)