2012-06-04 4 views
2

Я запутался в одной странной вещи .... У меня есть unsigned char array .... Я выделяю его с помощью calloc и записываю в него некоторые данные в байтах ... но когда я освобождаюсь этот unsigned char и выделите его еще раз, я вижу, что он сохраняет тот же адрес в памяти, который был назначен ранее. Я понимаю, почему ... Но я не могу понять, почему данные, которые я пытаюсь написать там второй раз, не написаны ... Там написаны данные, которые были написаны впервые ... Может ли кто-нибудь объяснить мне это? ??????unsigned char alloc и бесплатная проблема

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

Это, как я передать его .... На самом деле моя проблема заключается в том, что из-за этого распределения, которое происходит один раз каждые 2 секунды у меня есть утечка памяти ... Но когда я пытаюсь освободить выделяется сектор памяти случается, что описано выше .... :(

Пожалуйста, если кто-нибудь может мне помочь .... я бы так рад ... Вот код ...

- (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; } 

в этом коде нет части где я свободен (rawData), и потому, что я не могу освободить его внутри этого метода, я попытался определить rawData глобально и освободить его после вызова этого метода ... но ничего интересного ....

Пожалуйста, если кто-нибудь может мне помочь. ... Я был бы так рад ...

+0

Вам нужно будет предоставить полный фрагмент кода, который отображает как распределения, так и записи буфера, и как вы проверяете содержимое. Вышеупомянутое недостаточно, чтобы ответить на ваш вопрос. – gavinb

+0

@ gavinb done ... Любая интересная идея? – Garnik

ответ

1

Хорошо, поэтому этот метод отображает UIImage в только что выделенный буфер байта и возвращает буфер вызывающему. Поскольку вы назначаете его calloc, он будет инициализирован 0, а затем будет перезаписан содержимым изображения.

, когда я освобождаю этот символ без знака и передать его снова, я вижу, что она оставляет за собой один и тот же адрес в памяти, который был выделен предыдущий раз

Да, нет никаких гарантий относительно расположения буфера в памяти. Предполагая, что вы вызываете free() в возвращенную память, запрос на тот же размер, скорее всего, даст вам тот же самый буфер. Но - как вы проверяете, что содержимое не написано во второй раз? Что такое ? в буфере?

моя проблема заключается в том, что из-за это распределение, которое происходит один раз каждые 2 секунд у меня есть утечка памяти ... Но когда я пытаюсь освободить выделенный сектор памяти случается, что описано выше .... :(

Если есть утечка, это, скорее всего, в коде, вызывающем этот метод, поскольку здесь нет очевидной утечки. Семантика, очевидно, такова, что вызывающий отвечает за освобождение буфера. Так как это делается?

Также, вы подтверждаете правильность создания CGBitmapContext? Возможно, что так me флагов создания или параметры могут привести к ошибке. Поэтому добавьте проверку на то, что context действителен (по крайней мере, не равен нулю). Это может объяснить, почему содержимое не перезаписывается.

Один простой способ гарантировать, что ваша память обновляется, - это написать свои собственные данные. Вы можете заполнить буфер счетчиком и проверить это вне метода.Например, как раз, прежде чем вернуться rawData:

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

Это будет цикл через написание 0-255 в буфер, который можно легко проверить.

Другое дело - чего вы пытаетесь достичь с помощью этого кода? Возможно, вам будет проще достичь того, чего вы пытаетесь достичь. Возвращение нечетких буферов, лишенных метаданных, не обязательно является лучшим способом управления вашими изображениями.

+0

Цель моего проекта - написать инструмент скриншотов. Используя этот метод, я хочу получить пиксельные цвета и сравнить с предыдущим изображением для сходства. Тогда в другом методе я получаю разницу между этими двумя фотографиями и отправляю измененную часть. Все эти части сделаны, но у меня есть эта утечка. Я уверен в контексте, потому что каждый раз получаю следующую картинку. А также я попытался установить память на нуль memset (rawData, 0, weight * height * 4); после того как я освобожу его, но все тот же. Я понимаю, почему он возвращает один и тот же адрес каждый раз, но я не могу понять, почему метод CGBitmapContextCreate не перезаписывает данные внутри. – Garnik

+0

А также я уверен, что утечка находится в распределении rawData ... Проверено сотнями способов ... – Garnik

+0

Да, я знаю порядок param ... но это не поможет мне – Garnik

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 и этим I имел два указателя на тот же адрес памяти ... Так вот отсюда возникла проблема ... Я изменил эту часть задания на эту memcpy (rawDataForOldImage, rawDataForNewImage, newCapturedImage.size.width * newCapturedImage.size.height * 4); и здесь проблема решена .... Спасибо всем