Форум программистов, компьютерный форум, киберфорум
Программирование iOS/iPhone
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
107 / 107 / 9
Регистрация: 02.06.2009
Сообщений: 578
1

Есть ли здесь утечка памяти?

06.07.2013, 13:24. Показов 2216. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Вот код:
Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
-(NSString *)getCookie
{
    NSMutableURLRequest *cookieRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://google.ru"]];
    [cookieRequest setHTTPMethod:@"GET"];
    
    NSHTTPURLResponse *response = nil;
    NSError *error = nil;
    
    [NSURLConnection sendSynchronousRequest:cookieRequest returningResponse:&response error:&error];
    [cookieRequest release];
    if (error != nil)
    {
        [error release];
        return nil;
    }
    else
    {
        [error release];
        return [[[response allHeaderFields] objectForKey:@"Set-Cookie"] substringToIndex:[[[response allHeaderFields] objectForKey:@"Set-Cookie"] rangeOfString:@";"].location];
    }
}
Есть ли здесь утечка памяти? Особенно интересует момент с возвратом - уничтожится ли response или нет?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
06.07.2013, 13:24
Ответы с готовыми решениями:

Есть ли утечка памяти?
Пример добавления элемента в список. // Включение в список нового компонента void...

Есть ли утечка памяти в list
Здравствуйте, форумчане, есть вопрос насчет освобождения памяти в list, каждый элемент которого...

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

Есть ли утечка памяти в этом случае?
_Доброго денёчка всем. Прохожу тему на указатели и ссылки. Делаю упражнение на тему "написать...

16
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 13:35 2
сделай product->analyze и он все покажет(очень удобно быстро проверить на наличие возможных проблем). Или в instruments проверь
2
44 / 44 / 3
Регистрация: 27.05.2013
Сообщений: 163
06.07.2013, 15:19 3
Однозначно есть...
ты посылаешь объектам сообщение release... хотя ты им не делал alloc/retain...
0
107 / 107 / 9
Регистрация: 02.06.2009
Сообщений: 578
06.07.2013, 17:47  [ТС] 4
Прогон анализатором показал, что cookieRequest релизить не надо.
Pro2005, а почему релиз error - неверный? Я просто думал, что стандартные конструкторы и функции автоматически делают alloc встроенным типам.
Я просто только начинаю с Obj-C, поэтому не совсем понял механизма работы с памятью. Не подскажете, локальные переменные автоматически освобождаются при выходе из тела метода? Если нет - как быть с response?
Посоветуйте, пожалуйста, где можно подробно ознакомиться с механизмом работы с памятью в Objective-C :-)

Добавлено через 2 минуты
Pro2005, и, насколько я понял и пробовал - release невыделенного объекта не вызывает утечки. У меня просто вылетала ошибка неверного обращения к памяти. Меня интересует утечка именно в смысле потери выделенного места (без его возврата в пул), которая скорее всего будет для response.
0
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 18:02 5
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от Veyron Посмотреть сообщение
Не подскажете, локальные переменные автоматически освобождаются при выходе из тела метода? Если нет - как быть с response?
для того что бы не было утечек в таких случаях посылается autorelease
а вообще вот тут все подробно написано
3
107 / 107 / 9
Регистрация: 02.06.2009
Сообщений: 578
06.07.2013, 19:19  [ТС] 6
Xavier, и правда, статьи там очень хороши. Что ни говори - официальная документация всегда лучше всего :-)

Однако я не нашел ответ на один свой вопрос:
Objective-C
1
2
NSNumber *number = [[NSNumber alloc] init];
NSNumber *number_too = number;
Какой тогда будет счетчик ссылок на этот объект?
0
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
06.07.2013, 19:34 7
так и останется 1 ты просто указываешь number_too и number на один и тот же объект не увеличивая при этом счетчика ссылок. Вообще можешь проверить послав сообщение retainCount оно как раз возвращает кол-во ссылок
и только если потом ты пошлешь number_too сообщение retain то тогда счетчик будет =2, а вот если ты напишешь [number release] без удержания то потом при попытке обратиться к number_too будет ошибка.
1
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603
07.07.2013, 00:31 8
получаем что :

retain увеличивает счетчик
release уменьшает
autorelease уменьшает автоматически по-окончанию блока
присваивание к strong свойству опять увеличивает
при вызове конструктора [[objectClass alloc] init] он же [objectClass new] счетчик ссылок всегда равен 1

поправьте если что неверно
0
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
07.07.2013, 11:55 9
noname_club, По сути все правильно. Только autorelease не уменьшает счетчик а помещает объект в autorelease pool, а вот по окончании блока autorelease pool-а все объекты которые входят в него получают сообщение release, и сообщение release они получают столько же раз сколько получили сообщение autorelease.

Добавлено через 12 минут
А вообще используйте ARC
1
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603
07.07.2013, 12:26 10
дополнительно на рассмотрение

1) код без утечек

Objective-C
1
2
3
4
5
6
7
8
9
10
    NSMutableString* s1 = [NSMutableString stringWithFormat:@"Hello"];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
2) код с утечками

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
    NSMutableString* s1 = [NSMutableString new];
    
    
    
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
в обоих случаях счетчик показывает 1, => они должны утекать в обоих случаях, однако течет только в 2

идем дальше
3)

Objective-C
1
2
3
4
5
6
7
8
9
10
    NSMutableString* s1 = [[NSMutableString new] autorelease];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
не течет, чтото мне подсказывает что в методе NSMutableString stringWithFormat уже по-умолчанию стоит autorelease

теперь проверим как ведет себя autorelease при принудительном уменьшении ссылки

4)

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
    NSMutableString* s1 = [[NSMutableString new] autorelease];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
    
    [s1 release]; // << уменьшение ссылки
не получилось EXC_BAD_ACCESS

проверим как ведет себя "скрытый autorelease" в методе stringWithFormat, ведь мы не ожидаем что там он там прописан

5)

Objective-C
1
2
3
4
5
6
7
8
9
10
11
12
   NSMutableString* s1 = [NSMutableString stringWithFormat:@"Hello world"];
 
    for (int i = 0; i<100000; i++) {
        if (i<10) {
            NSLog(@"%@",s1);
        }
        [s1 appendString:@"Hello world"];
    }
    
    NSLog(@"count is %d ",[s1 retainCount]);
    
    [s1 release]; // << уменьшение ссылки
получилось

однако появилась странная надпись

test_ARC(690,0xac1cda28) malloc: *** error for object 0x753ad90: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
что как бы означает что релизить нельзя

чтобы разобраться в сабже идем в гугл и видим там

http://stackoverflow.com/quest... withformat
You never release it. It's autoreleased already.

You only ever release objects which were given to you via methods whose names begin with +alloc, +new -copy, -mutableCopy, or -retain. If the name begins with anything else, you don't own it and are not responsible for releasing it.
что дословно означает: Если вы используете в конструкторе +alloc, +new -copy, -mutableCopy, or -retain тогда требуется релизить

------

Из этого можно сделать вывод, что без использования ARC, нужно во всех ваших классах писать конструкторы со словом init

например:

initWithData
initWithObject и прочее чтобы было видно что autorelease не используется.

---

я так гуглу походил, внятного ответа как распознать autorelease объект там нет.
=> только тестированием и использованием статических методов названием с init и прочими, которые указывали что autorelease не используется
0
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
07.07.2013, 13:14 11
Правила довольно простые.
Если тебе нужен объект которым ты будешь владеть, т:е. грубо говоря сам управлять его жизненным циклом, ты должен явно его создать с помощью всего нескольких методов: alloc, init (и все разновидности init по типу initWith...)
или new или же удержать объект с помощью copy или retain. Все эти объекты не будут помещены в autorelease pool пока ты не сам не пошлешь сообщение autorelease. И за этими объектами надо следить, забудешь release или autorelease все утечка.

Все же остальные объекты созданные с помощью "convenience constructors" такими как arrayWaithArray, stringWithString и т.д. , т.е по соглашению не включающие слова: alloc, init, new, будут автоматически помещены в autorelease pool ибо эти методы возвращают по принципу :
Objective-C
1
return [[[NSString alloc] initWithString:@"some string"] autorelease];
2
107 / 107 / 9
Регистрация: 02.06.2009
Сообщений: 578
07.07.2013, 21:10  [ТС] 12
Xavier, а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
0
112 / 103 / 12
Регистрация: 01.05.2013
Сообщений: 603
07.07.2013, 22:19 13
а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
Семантика сеттеров свойств

strong - обозначает строгое переназначение объекта, делая указатель на объект владельцем этого объекта

weak - в отличии от strong обозначает нестрогое соответствие и если объект был освобожден из памяти (из другого класса или потока), то значение установится в nil. Не поддерживается OS X v10.6 и iOS 4; используйте assign

copy - указывает на то, что для присваивания будет использована копия переданного объекта. Первоначальному объекту посылается сообщение release. Может быть использовано только для объектов, поддерживающих протокол NSCopying, например NSString.

assign - для задания нового значения используется оператор присваивания. Используется только для скалярных типов (NSInteger и CGRect) либо для объектов, которыми мы не владеем.

retain - укaзывает на тo, что для объекта, используемого в качестве нового значения instance-переменной, управление памятью происходит вручную (не забываем потом освободить память).

Atomic

nonatomic - делает более быстрым способ доступа к объекту в немногозадачной среде, так-как в случае с atomic (по умолчанию все акцессоры atomic) и использованием strong, copy, или retain, во избежание коллизий с возможностью доступа к свойству из других потоков в сеттере строится код блокирующий переключение между потоками.
1
Peace 2 all shining faces
674 / 535 / 85
Регистрация: 05.03.2010
Сообщений: 1,282
07.07.2013, 22:42 14
Цитата Сообщение от Veyron Посмотреть сообщение
а где еще можно почитать о спецификаторах в свойствах (assing, weak, retain, strong...) ?
блин, да в оффициальной документации http://developer.apple.com/lib... gData.html

Цитата Сообщение от noname_club Посмотреть сообщение
Из этого можно сделать вывод, что без использования ARC, нужно во всех ваших классах писать конструкторы со словом init
например:
initWithData
initWithObject и прочее чтобы было видно что autorelease не используется.
---
я так гуглу походил, внятного ответа как распознать autorelease объект там нет.
=> только тестированием и использованием статических методов названием с init и прочими, которые указывали что autorelease не используется
к чему пустая трата времени и какие-то лишние выводы?
все же отлично расписано в документации, зачем этот stackoverflow-driven development от таких же "самоучек" как вы?
на блюдечке все ведь разложено, а вы там целую дисертацию навояли и то размытую
https://developer.apple.com/li... 000011-SW1
1
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
07.07.2013, 23:25 15
Цитата Сообщение от noname_club Посмотреть сообщение
strong - обозначает строгое переназначение объекта, делая указатель на объект владельцем этого объекта
weak - в отличии от strong обозначает нестрогое соответствие и если объект был освобожден из памяти (из другого класса или потока), то значение установится в nil. Не поддерживается OS X v10.6 и iOS 4; используйте assign
copy - указывает на то, что для присваивания будет использована копия переданного объекта. Первоначальному объекту посылается сообщение release. Может быть использовано только для объектов, поддерживающих протокол NSCopying, например NSString.
assign - для задания нового значения используется оператор присваивания. Используется только для скалярных типов (NSInteger и CGRect) либо для объектов, которыми мы не владеем.
что то как то мудрено все
как написал Vorona можно почитать в офф документации там все понятно написано или вот тут
также исходя из всего этого:

strong = retain и вот что пишут apple: strong is the default. An object remains “alive” as long as there is a strong pointer to it.

assign = unsafe_unretained и опять же apple пишут: specifies a reference that does not keep the referenced object alive and is not set to nil when there are no strong references to the object. If the object it references is deallocated, the pointer is left dangling.

а weak это: specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
weak и assign похожи, но есть небольшая разница она описана выше.
1
107 / 107 / 9
Регистрация: 02.06.2009
Сообщений: 578
08.07.2013, 16:27  [ТС] 16
Еще такой вопрос: как происходит работа с объектом в NSMutableArray addObject: ? В офф доке написано назначение метода, но не написали его поведение - он ритейнит объект, делает копию или просто добавляет указатель в контейнер?

Добавлено через 1 минуту
Судя по тому, что
Parameters
anObject
The object to add to the end of the array's content. This value must not be nil.
Явно не просто указатель. Тогда копирование или retain?
0
in god we trust
74 / 74 / 8
Регистрация: 20.04.2012
Сообщений: 201
08.07.2013, 16:37 17
да он просто ретеинит объект, но тебе об этом заботиться не надо.
1
08.07.2013, 16:37
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.07.2013, 16:37
Помогаю со студенческими работами здесь

Есть ли утечка памяти в проекте? И как можно это перепроверять?
#include &quot;stdafx.h&quot; #include &lt;iostream&gt; using namespace std; class MyArray { int *ptrarray;...

Здесь есть какие нибудь ошибки ? и как здесь получается в ответе 6.25?
program r2; var b:real; begin b:=100; repeat b:=b/2; until b&lt;10; writeln (b:0:2); end. ...

HttpWebRequest, расход памяти непомерно больших объемов и , как следствие, утечка памяти
Добрый вечер. Мне была поставлена такая задача. Написать приложение, которая загружает из списка...

Вектор, утечка памяти, функция создания и выделение памяти
Здравствуйте. Есть проблема. функция malloc выделяет память лишь в функции CreateVector(), и при...

Утечка памяти
Доброго времени суток, форумчане. Помогите справиться с утечкой памяти, не понятно где зараза...

Утечка памяти
Утечка оперативной памяти за 30-40 мин. В диспетчере задач говорит что осталось 1-2% памяти но где...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru