0

私は、ファイルからbase64でエンコードされた文字列に画像データをトランスコードし、NSStreamを使用してファイルが読み取られるときにバイトに戻す作業を行っています。もうすぐそこにいると思いますが、変換中のさまざまな時点でEXC_BAD_ACCESSに遭遇し続けます。

私はNSStreamとバッファの世界にかなり慣れていないので、ここで絶対に間違ったアプローチを取っている場合は、遠慮なく知らせてください。

これが私がこれまでに得たものです:

// Copy the bytes from our file input stream buffer
void *base64buffer = malloc(self.buffer[self.bufferOffset]);

// Convert the bytes to NSData for the base64 encode
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];

// Convert our NSData into a base64 encoded string
NSString *base64EncodedData = [dataToEncode base64EncodedString];

// Convert our base64 encoded string back into NSData
NSData *encodedData = [base64EncodedData dataUsingEncoding:NSUTF8StringEncoding];

// Write the bytes to our output stream
bytesWritten = [self.producerStream write:[encodedData bytes] maxLength:[encodedData length]];

// Clean up
dataToEncode = nil;
base64EncodedData = nil;
encodedData = nil;
free(base64buffer);
4

2 に答える 2

5

ここでいくつかの問題:

// Copy the bytes from our file input stream buffer
void *base64buffer = malloc(self.buffer[self.bufferOffset]);

これはあなたのコメントが言っていることをしません。あなたが今やったことは、size_t(4バイトまたは8バイトの符号なし整数)と同じサイズのself.buffer[self.bufferOffset] バッファを割り当てられます。基本的に、基本的にランダムなサイズのバッファを割り当てようとします。サイズが大きすぎると、NULLが返され、それがクラッシュの原因である可能性があります。

// Convert the bytes to NSData for the base64 encode
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];

これはあなたが思っていることをしません。 sizeof(base64buffer)32ビットモードと64ビットモードのどちらでコンパイルしているかに応じて、4または8のいずれかになります。これはポインタのサイズであり、バッファのサイズではありません。

free(base64buffer);

最初のNSDataを作成したとき、「freeWhenDone」に「はい」と答えました。これは、NSDataが所有権を取得し、base64buffer割り当てが解除されたときに解放しようとすることを意味します。あなたはすでにそれを解放しているので、その操作は予測できない厄介な方法で失敗します。


どうすればこれを修正できますか?次のようなものを試してください。

size_t bufferLengthInBytes = .... // you'll need to figure out how to get this

// Next, instead of mallocing my own buffer for the data, I'll let the runtime do it for me.
// I'm assuming that self.buffer is a pointer to the bytes you want to copy.
NSData* dataToEncode = [NSData dataWithBytes: self.buffer length:bufferLengthInBytes];

// I'm not sure where the method base64EncodedString comes from.  I assume you have a category to do this.
NSString *base64EncodedString = [dataToEncode base64EncodedString];

残りのメソッドは、解放するためのバッファーがもうないことを除いて同じである必要があります(実際、以前は実際にはありませんでした)。

于 2010-10-04T09:07:51.517 に答える
3
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];

freeWhenDone:YESであるため、dataToEncodeの割り当てが解除されると、この行はfree(base64buffer)を実行します。したがって、同じメモリスペースを2回解放します。

于 2010-10-04T10:42:53.290 に答える