вот мучаю такую конструкцию(кусок плугина к миранде, который позволяет сохранять и поднимать контакт-лист в удобоваримом виде):
void createParentGroups(const char *groupName) { if ( strrchr(groupName,'\\') != NULL ) { char *duplicate; duplicate = strdup(groupName); if( duplicate == NULL ) MessageBox(NULL, Translate("Insufficient memory available"), Translate("Error"),MB_OK); else { char *pos; pos = strrchr(duplicate,'\\'); //Find the last \ character if (pos != NULL) { *pos = 0; // Nullterminate the string where the last \ was found createGroup(duplicate); } else { MessageBox(NULL, Translate("A critical error occured.\nTry to do the operation one more time."), Translate("Critical error"),MB_OK); } } free( duplicate ); //Since strdup calls malloc it is good to free the space allocated } return; } void createGroup(const char *groupName) { if (!groupExistsOLD(groupName)) { int groupId; char groupIdStr[11]; DBVARIANT dbv; char *groupName2; createParentGroups(groupName); // Create the parentgroups if needed groupName2 = malloc(strlen(groupName + 2)); groupName2[0] = 1; // This is because the DB requires the groupname to begin with the second character in the string groupName2[1] = 0; strcat(groupName2, groupName); // Find the right id for the group for(groupId = 0;; groupId++) { itoa(groupId, groupIdStr,10); if(DBGetContactSetting(NULL, "CListGroups", groupIdStr, &dbv)) break; DBFreeVariant(&dbv); } DBWriteContactSettingString(NULL,"CListGroups", groupIdStr, groupName2); free( groupName2 ); } return; }
Вызывается в случае, если при импорте контакта не оказалось группы, в которой он должен лежать.
Группа передается в аргументах в виде Жилкомсбыт\По работе с физическими лицами отдел
... эта конструкция виснет на второй итерации при попытке выполнить free( groupName2 ); ...
... закоментил, откомпилил ... на машине с двумя гигами оперативы пашет замечательно ... на 256 - вылетает после создания первой группы (но первую - создает)
... вижу, что написано умнО ... но коряво с точки зрения использования памяти. ... что делать?
Добавлено спустя 1 час 30 минут 54 секунды:
Вроде нашел косяк ... только не совсем понятно, почему оно начало работать ... поменял
groupName2 = malloc(strlen(groupName + 2));
groupName2 = malloc(strlen(groupName) + 2);
groupName2 = malloc(strlen(groupName + 2));
дык. потому что тута берется кусок от groupName, начиная с третьего символа... а тута:groupName2 = malloc(strlen(groupName) + 2);
просто резервируется кусок памяти размером длина groupName + 2 байта хотя, наверное, это будет еще корректнее:groupName2 = malloc(strlen(groupName + 2) + 2);
но точно не уверенАццкий ромбовод {:€
Я пока не волшебник - я только учусь! :-P
Странная конструкция, для ф-ии strlen дается строка groupName начиная с 3-го символа. А если в groupName лежит строка длиной в 1 символ? Тогда strlen попрет по памяти в поисках 0, возможно найдет его где-то, и возвратит какое-то число, именно на это число байт и попытается выделить память malloc.
Верный вариант конечно этот:
dimm
фишка в том, что ниже там же написано:
т.е. содержательная часть groupName начинается с третьего символа, а первые два символы с кодами 0x01 и 0x00. Вот меня волнует вопрос - а не споткнется ли strlen тута (т.е. напишет, что строка "всего лишь" 2 символа)... Мы ж то не знаем 100%, что же в эту функцию передается
так что имхо:
groupName2 = malloc(strlen(groupName + 2) + 2);
т.е. подсчитать длину содержательной части groupName + добавить два резервных байта...
Аццкий ромбовод {:€
Я пока не волшебник - я только учусь! :-P
Нет,
неверно! При groupName состоящей из 1 символа strlen() вернет неизвестно что.
Вообще правильно вот так:
так как там в комментарии подписано:
т.е. DB требует, чтобы groupname начинался со второго символа, поэтому они в первый пихают 1, затем сразу 0, т.е. длину строки делают = 1. А затем вызывают strcat() - которая объединяет 2 строки:
т.е. в строку groupName2 добавляют содержимое строки groupName, таким образом длина строки groupName2 должна быть на 1 больше чем groupName, т.к. в начале записана 1.
убедили почти. Только теперь меня берут сомнения:
у нас strlen возвращает длину строки без \0. Т.е. длина groupName2=длина groupName + 1 (на "\0") + 1 (и на 1-ку в самом начале)
так что правильный вариант:
Аццкий ромбовод {:€
Я пока не волшебник - я только учусь! :-P
Ага, точно, прогнал, забыл про strlen() и \0
Тоесть получается, что я то какраз все верно нашел ... кул.
Отправить комментарий