3 ms·
I'm not sure what issue you're seeing with getdelim(). It never releases the underlying memory, AFAICT. You always need to call free at the end of the loop, r
by abbeyj 4y ago
I'm not sure what issue you're seeing with getdelim(). It never releases the underlying memory, AFAICT. You always need to call free at the end of the loop, regardless of whether there was a read error, a realloc failure, you hit EOF, or you broke out of the loop early. So why wouldn't the following be OK?
std::unique_ptr<char, free_deleter> line;
size_t len = 0;
while ((read = getdelim(std::inout_ptr(line), &len, delim, fp)) != -1) {
// ...
}
If the getdelim call ends up calling realloc and succeeding then we want to forget about the old pointer and not call `free` on it. We want to remember the new pointer and call `free` on that when we're done with the loop. That's what std::inout_ptr gets for us. It calls release() before the getdelim call and then calls reset() with the new value after the getdelim call.
If there is an I/O error or a realloc failure at some point in the file then `line` is left unmodified, pointing to the existing buffer. We still need to free that so keeping it under the control of the smart pointer is the right thing to do.
This seems like a perfect fit for std::inout_ptr.
The situation asprintf() is unfortunate. If it had been designed to set the out parameter to NULL on error or just to guarantee that it was unmodified on error then it would work with std::out_ptr. Unfortunately they decided that the out pointer would be instead be undefined on error so it is not safe to use with std::out_ptr.