Line57在栈上分配一个SkBitmap
53 jobject webcoreImageToJavaBitmap(JNIEnv* env, WebCore::Image* icon) 54 {
55 if (!icon)
56 return NULL;
57 SkBitmap bm;
58 WebCore::SharedBuffer* buffer = icon->data();
59 if (!buffer || !SkImageDecoder::DecodeMemory(buffer->data(), buffer->size(),
60 &bm, SkBitmap::kNo_Config,
61 SkImageDecoder::kDecodePixels_Mode))
62 return NULL;
63
64 return GraphicsJNI::createBitmap(env, new SkBitmap(bm), false, NULL);
65 }
这个Bitmap在Line64行传入GraphicsJNI::createBitmap; new SkBitmap(bm)实际调用:
91 SkBitmap::SkBitmap(const SkBitmap& src) {
92 SkDEBUGCODE(src.validate();)
93 sk_bzero(this, sizeof(*this));
94 *this = src;
95 SkDEBUGCODE(this->validate();)
96 }
和
103 SkBitmap& SkBitmap::operator=(const SkBitmap& src) { ...}
当fPixelRef为null时,fPixels保存真正的bitmap pixel,这个fPixels同时保存在line57的bitmap和line64的new SkBitmap(bm)。这是因为在SkBitmap::operator=()中,等号左边的bitmap没有allocate内存。查看GraphicsJNI::createBitmap同样没有分配新内存。
这样问题就来了,webcoreImageToJavaBitmap()返回,line57的bitmap会自动调用析构函数,导致freefPixels。这时line64的GraphicsJNI::createBitmap还用这个bitmap的fPixels,但bitmap的fPixels已经指向无效内存了。
如何防止这类问题?
这是bitmap共用fPixels导致的错误,对拷贝构造或赋值重载中没有为新对象分配新资源,而是通过指针与原对象共享资源,在析构函数中又没有判断是否有对象还在使用这个资源,就释放这个资源。就应该多检查一下。是否有可能发生这样的问题。
减少无用的对象数,也可以避免这类问题。对这个问题把line57改成:
SkBitmap* bm = new SkBitmap();
把line64改成:
return GraphicsJNI::createBitmap(env, bm, false, NULL);
就解决这个问题。
阅读(2618) | 评论(0) | 转发(0) |