我正在将图像数据从文件转换为base64编码的字符串,然后在使用NSStream读取文件时转换回字节。我想我就快到了,但在转换过程中,我总是在不同的地方遇到EXC_BAD_ACCESS。
我对NSStream和buffers的世界还很陌生,所以如果我在这里采用了完全错误的方法,请随时告诉我。
这是我到目前为止所得到的:
// 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);发布于 2010-10-04 17:07:52
这里有几个问题:
// 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)是4还是8取决于您是在32位还是64位模式下编译。它是指针的大小,而不是缓冲区的大小。
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-04 18:42:53
NSData *dataToEncode = [NSData dataWithBytesNoCopy:base64buffer length:sizeof(base64buffer) freeWhenDone:YES];当释放freeWhenDone:__YES.时,此行将执行dataToEncode释放(Base64buffer),因为因此,您将释放相同的内存空间两次。
https://stackoverflow.com/questions/3852946
复制相似问题