2

私は 1 つの奇妙なことについて混乱しています....私は unsigned char 配列を持っています.... calloc を使用してそれを割り当て、その中にいくつかのバイトデータを記録します...しかし、この unsigned char を解放して再度割り当てると、前回割り当てられたメモリ内の同じアドレスが予約されていることがわかります。理由はわかります....しかし、2回目に書き込もうとしているデータが書き込まれない理由がわかりません...最初に書き込まれたデータが書き込まれています....誰か私にこれを説明してもらえますか? ??????

unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));

これが私がそれを割り当てる方法です....実際に私の問題は、この割り当てのために2秒ごとに1回発生するため、メモリリークが発生することです...しかし、割り当てられたメモリセクターを解放しようとすると、上記のことが起こります... .:(

誰かが私を助けることができれば....私はとてもうれしいです...ここにコードがあります...

- (unsigned char*) createBitmapContext:(UIImage*)anImage{

CGImageRef imageRef = [anImage CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;

NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

CGContextRelease(context);

imageRef=nil;
return rawData; }

このコードには free(rawData) する部分がありません。このメソッド内で解放できないため、rawData をグローバルに定義し、このメソッドを呼び出した後に解放しようとしましたが、何も興味深いことはありません....

誰かが私を助けることができれば....私はとてもうれしいです...

4

2 に答える 2

1

わかりました。このメソッドはUIImage、新しく割り当てられたバイト バッファーに a をレンダリングし、そのバッファーを呼び出し元に返します。で割り当てているためcalloc、0 に初期化され、画像の内容で上書きされます。

この unsigned char を解放して再度割り当てると、前回割り当てられたのと同じアドレスがメモリに予約されていることがわかります

はい、メモリ内のバッファの場所に関する保証はありません。返されたメモリを呼び出すと仮定するとfree()、まったく同じサイズを要求すると、同じバッファが返される可能性が非常に高くなります。しかし、内容が二度書きされていないことをどのように確認していますか? バッファには何が入っていますか?

私の問題は、2秒ごとに1回発生するこの割り当てのために、メモリリークが発生することです...しかし、割り当てられたメモリセクターを解放しようとすると、上記のことが起こります....:(

リークがある場合は、このメソッドを呼び出すコードにある可能性があります。ここには明らかなリークがないためです。セマンティクスは明らかに、呼び出し元がバッファーを解放する責任があるようなものです。それで、それはどのように行われますか?

CGBitmapContextまた、 が正しく作成されていることを確認していますか? 一部の作成フラグまたはパラメーターがエラーになる可能性があります。そのため、有効であることのチェックを追加しcontextます (少なくとも nil ではありません)。これにより、コンテンツが上書きされない理由が説明できます。

メモリが新しく更新されていることを確認する簡単な方法の 1 つは、メモリに独自のデータを書き込むことです。バッファーにカウンターを入力し、メソッドの外部でこれを確認できます。たとえば、戻る直前にrawData:

static unsigned updateCounter = 0;
memset(rawData, updateCounter & 0xff, width*height*4);

これにより、0 ~ 255 がバッファに書き込まれます。これは簡単に確認できます。

別のこと-このコードで何を達成しようとしていますか? あなたが達成しようとしていることを達成するためのより簡単な方法があるかもしれません。メタデータのないベア バッファを返すことは、イメージを管理するための最良の方法であるとは限りません。

于 2012-06-04T12:38:53.750 に答える
0

みんな私はこの問題を解決しました...最初にcreateBitmapContextメソッドをこれに変更しました

- (void) createBitmapContext:(UIImage*)anImage andRawData:(unsigned char *)theRawData{

CGImageRef imageRef = [anImage CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
//    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
bytesPerPixel = 4;
bytesPerRow = bytesPerPixel * width;

NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(theRawData, width, height,
                                             bitsPerComponent, bytesPerRow, colorSpace,
                                             kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);

CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);

CGContextRelease(context);
imageRef=nil;
//    return theRawData;}

それから...これに加えて、newRawDataをoldRawDataに割り当てる部分を逃しました。これにより、同じメモリアドレスへの2つのポインターがありました...ここから問題が発生しました...この割り当て部分をこの memcpy( rawDataForOldImage、rawDataForNewImage、newCapturedImage.size.width*newCapturedImage.size.height*4); そしてここで問題は解決しました....すべてに感謝します

于 2012-06-05T14:48:20.127 に答える