Commit b89b1d772db935ed36b8abe8a21ee6468ada3d23
1 parent
93de6eaf
Fix memory leak in pdf-invert-images
A class can't have a PointerHolder to itself since PointerHolder doesn't have the concept of weak references.
Showing
1 changed file
with
13 additions
and
16 deletions
examples/pdf-invert-images.cc
| ... | ... | @@ -40,12 +40,12 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider |
| 40 | 40 | virtual void provideStreamData(int objid, int generation, |
| 41 | 41 | Pipeline* pipeline) override; |
| 42 | 42 | |
| 43 | - void setSelfPh(PointerHolder<QPDFObjectHandle::StreamDataProvider>); | |
| 44 | - void registerImage(QPDFObjectHandle image); | |
| 43 | + void registerImage( | |
| 44 | + QPDFObjectHandle image, | |
| 45 | + PointerHolder<QPDFObjectHandle::StreamDataProvider> self); | |
| 45 | 46 | |
| 46 | 47 | private: |
| 47 | 48 | QPDF other; |
| 48 | - PointerHolder<QPDFObjectHandle::StreamDataProvider> self_ph; | |
| 49 | 49 | // Map og in original to copied image |
| 50 | 50 | std::map<QPDFObjGen, QPDFObjectHandle> copied_images; |
| 51 | 51 | }; |
| ... | ... | @@ -56,18 +56,18 @@ ImageInverter::ImageInverter() |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | void |
| 59 | -ImageInverter::setSelfPh(PointerHolder<QPDFObjectHandle::StreamDataProvider> p) | |
| 59 | +ImageInverter::registerImage( | |
| 60 | + QPDFObjectHandle image, | |
| 61 | + PointerHolder<QPDFObjectHandle::StreamDataProvider> self) | |
| 60 | 62 | { |
| 61 | 63 | // replaceStreamData requires a pointer holder to the stream data |
| 62 | 64 | // provider, but there's no way for us to generate one ourselves, |
| 63 | - // so we have to have it handed to us. | |
| 64 | - this->self_ph = p; | |
| 65 | -} | |
| 66 | - | |
| 65 | + // so we have to have it handed to us. Don't be tempted to have | |
| 66 | + // the class contain a PointerHolder to itself as a member. Doing | |
| 67 | + // this will prevent the class from ever being deleted since the | |
| 68 | + // reference count will never drop to zero (and PointerHolder | |
| 69 | + // doesn't have weak references). | |
| 67 | 70 | |
| 68 | -void | |
| 69 | -ImageInverter::registerImage(QPDFObjectHandle image) | |
| 70 | -{ | |
| 71 | 71 | QPDFObjGen og(image.getObjGen()); |
| 72 | 72 | // Store information about the images based on the object and |
| 73 | 73 | // generation number. Recall that a single image object may be |
| ... | ... | @@ -88,7 +88,7 @@ ImageInverter::registerImage(QPDFObjectHandle image) |
| 88 | 88 | // filterable in the input QPDF object, so we don't have to deal |
| 89 | 89 | // with it explicitly here. We could explicitly use /DCTDecode and |
| 90 | 90 | // write through a DCT filter if we wanted. |
| 91 | - image.replaceStreamData(this->self_ph, | |
| 91 | + image.replaceStreamData(self, | |
| 92 | 92 | QPDFObjectHandle::newNull(), |
| 93 | 93 | QPDFObjectHandle::newNull()); |
| 94 | 94 | } |
| ... | ... | @@ -149,9 +149,6 @@ int main(int argc, char* argv[]) |
| 149 | 149 | |
| 150 | 150 | ImageInverter* inv = new ImageInverter; |
| 151 | 151 | PointerHolder<QPDFObjectHandle::StreamDataProvider> p = inv; |
| 152 | - // We need to give ImageInverter the pointer holder that it | |
| 153 | - // needs to pass to replaceStreamData. | |
| 154 | - inv->setSelfPh(p); | |
| 155 | 152 | |
| 156 | 153 | // For each page... |
| 157 | 154 | std::vector<QPDFPageObjectHelper> pages = |
| ... | ... | @@ -186,7 +183,7 @@ int main(int argc, char* argv[]) |
| 186 | 183 | (color_space.getName() == "/DeviceGray") && |
| 187 | 184 | (bits_per_component.getIntValue() == 8)) |
| 188 | 185 | { |
| 189 | - inv->registerImage(image); | |
| 186 | + inv->registerImage(image, p); | |
| 190 | 187 | } |
| 191 | 188 | } |
| 192 | 189 | } | ... | ... |