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,12 +40,12 @@ class ImageInverter: public QPDFObjectHandle::StreamDataProvider | ||
| 40 | virtual void provideStreamData(int objid, int generation, | 40 | virtual void provideStreamData(int objid, int generation, |
| 41 | Pipeline* pipeline) override; | 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 | private: | 47 | private: |
| 47 | QPDF other; | 48 | QPDF other; |
| 48 | - PointerHolder<QPDFObjectHandle::StreamDataProvider> self_ph; | ||
| 49 | // Map og in original to copied image | 49 | // Map og in original to copied image |
| 50 | std::map<QPDFObjGen, QPDFObjectHandle> copied_images; | 50 | std::map<QPDFObjGen, QPDFObjectHandle> copied_images; |
| 51 | }; | 51 | }; |
| @@ -56,18 +56,18 @@ ImageInverter::ImageInverter() | @@ -56,18 +56,18 @@ ImageInverter::ImageInverter() | ||
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | void | 58 | void |
| 59 | -ImageInverter::setSelfPh(PointerHolder<QPDFObjectHandle::StreamDataProvider> p) | 59 | +ImageInverter::registerImage( |
| 60 | + QPDFObjectHandle image, | ||
| 61 | + PointerHolder<QPDFObjectHandle::StreamDataProvider> self) | ||
| 60 | { | 62 | { |
| 61 | // replaceStreamData requires a pointer holder to the stream data | 63 | // replaceStreamData requires a pointer holder to the stream data |
| 62 | // provider, but there's no way for us to generate one ourselves, | 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 | QPDFObjGen og(image.getObjGen()); | 71 | QPDFObjGen og(image.getObjGen()); |
| 72 | // Store information about the images based on the object and | 72 | // Store information about the images based on the object and |
| 73 | // generation number. Recall that a single image object may be | 73 | // generation number. Recall that a single image object may be |
| @@ -88,7 +88,7 @@ ImageInverter::registerImage(QPDFObjectHandle image) | @@ -88,7 +88,7 @@ ImageInverter::registerImage(QPDFObjectHandle image) | ||
| 88 | // filterable in the input QPDF object, so we don't have to deal | 88 | // filterable in the input QPDF object, so we don't have to deal |
| 89 | // with it explicitly here. We could explicitly use /DCTDecode and | 89 | // with it explicitly here. We could explicitly use /DCTDecode and |
| 90 | // write through a DCT filter if we wanted. | 90 | // write through a DCT filter if we wanted. |
| 91 | - image.replaceStreamData(this->self_ph, | 91 | + image.replaceStreamData(self, |
| 92 | QPDFObjectHandle::newNull(), | 92 | QPDFObjectHandle::newNull(), |
| 93 | QPDFObjectHandle::newNull()); | 93 | QPDFObjectHandle::newNull()); |
| 94 | } | 94 | } |
| @@ -149,9 +149,6 @@ int main(int argc, char* argv[]) | @@ -149,9 +149,6 @@ int main(int argc, char* argv[]) | ||
| 149 | 149 | ||
| 150 | ImageInverter* inv = new ImageInverter; | 150 | ImageInverter* inv = new ImageInverter; |
| 151 | PointerHolder<QPDFObjectHandle::StreamDataProvider> p = inv; | 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 | // For each page... | 153 | // For each page... |
| 157 | std::vector<QPDFPageObjectHelper> pages = | 154 | std::vector<QPDFPageObjectHelper> pages = |
| @@ -186,7 +183,7 @@ int main(int argc, char* argv[]) | @@ -186,7 +183,7 @@ int main(int argc, char* argv[]) | ||
| 186 | (color_space.getName() == "/DeviceGray") && | 183 | (color_space.getName() == "/DeviceGray") && |
| 187 | (bits_per_component.getIntValue() == 8)) | 184 | (bits_per_component.getIntValue() == 8)) |
| 188 | { | 185 | { |
| 189 | - inv->registerImage(image); | 186 | + inv->registerImage(image, p); |
| 190 | } | 187 | } |
| 191 | } | 188 | } |
| 192 | } | 189 | } |