-
Notifications
You must be signed in to change notification settings - Fork 74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
silx.math.fit.peaks
: Fixed -Wuse-after-free
warning
#4147
Conversation
…t realloc works but not second
Tested in a |
realloc_peaks = realloc(peaks0, max_npeaks * sizeof(double));
if (realloc_peaks == NULL) {
// 2)
printf("Error: failed to extend memory for peaks array.");
*peaks = peaks0;
*relevances = relevances0; // ????
return(-n_peaks);
} else {
// 1) or 3) -> do not use peaks0 anymore
peaks0 = realloc_peaks;
// where is peaks pointing to? Shouldn't we do *peaks = peaks0; ?
} realloc_relevances = realloc(relevances0, max_npeaks * sizeof(double));
if (realloc_relevances == NULL) {
// 2)
printf("Error: failed to extend memory for peak relevances array.");
*peaks = peaks0; // ????
*relevances = relevances0;
return(-n_peaks);
}
else {
// 1) or 3) -> do not use relevances0 anymore
relevances0 = realloc_relevances;
// where is relevances pointing to? Shouldn't we do *relevances = relevances0; ?
} The original version has a different behavior realloc_peaks = realloc(peaks0, max_npeaks * sizeof(double));
realloc_relevances = realloc(relevances0, max_npeaks * sizeof(double));
if (realloc_peaks == NULL || realloc_relevances == NULL) {
printf("Error: failed to extend memory for peaks array.");
*peaks = peaks0;
*relevances = relevances0;
return(-n_peaks);
}
else {
peaks0 = realloc_peaks;
relevances0 = realloc_relevances;
} If one of the two realloc fails, you keep the original pointers but e.g. peaks0 is invalid when realloc_peaks!=NULL. So the compiler warning is warranted. However in the refactored form, what is the effect if one realloc fails and the other not? |
Looking at the code I see this in the beginning /* Output pointers */
*peaks = peaks0;
*relevances = relevances0; And at the end this *peaks = peaks0;
*relevances = relevances0;
return (n_peaks); Which probably why it was done as well in the early returns. But why? Since you do it in the beginning, shouldn't you only do it again when the peaks0 or relevances0 changes? I'm thinking it should be /* Output pointers */
*peaks = peaks0;
*relevances = relevances0;
...
realloc_peaks = realloc(peaks0, max_npeaks * sizeof(double));
if (realloc_peaks == NULL) {
printf("Error: failed to extend memory for peaks array.");
return (-n_peaks);
} else {
peaks0 = realloc_peaks;
*peaks = peaks0;
}
realloc_relevances = realloc(relevances0, max_npeaks * sizeof(double));
if (realloc_relevances == NULL) {
printf("Error: failed to extend memory for peak relevances array.");
return (-n_peaks);
}
else {
relevances0 = realloc_relevances;
*relevances = relevances0;
}
...
return (n_peaks); |
Or we do the opposite ...
realloc_peaks = realloc(peaks0, max_npeaks * sizeof(double));
if (realloc_peaks == NULL) {
printf("Error: failed to extend memory for peaks array.");
*peaks = peaks0;
*relevances = relevances0;
return (-n_peaks);
} else {
peaks0 = realloc_peaks;
}
realloc_relevances = realloc(relevances0, max_npeaks * sizeof(double));
if (realloc_relevances == NULL) {
printf("Error: failed to extend memory for peak relevances array.");
*peaks = peaks0;
*relevances = relevances0;
return (-n_peaks);
}
else {
relevances0 = realloc_relevances;
}
...
*peaks = peaks0;
*relevances = relevances0;
return (n_peaks); But a mixture of the two is confusing imo. |
The refactored form returns 2 valid pointers which is the expected behavior IMO.
Indeed, |
I updated to this PR to update |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Much clearer. Thanks!
Checklist:
<Module or Topic>: <Action> <Summary>
(see contributing guidelines)This PR aims at fixing
Wuse-after-free
warning with recent gcc (12 or 14?) reported in #4139.At least, it fixes the case of a first successful realloc for
peaks0
and a failed second realloc forrelevances0
(in which casepeaks0
points to freed memory).closes #4139