Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 20.04.2017, 15:41   #1
Paul_man
 
Регистрация: 28.02.2012
Сообщений: 3
По умолчанию Проблема с malloc

Есть функция, которая принимает путь реестра к сетевому адаптеру, открывает этот ключ и ищет в нём требуемые значения.
Код:
#define TOTALBYTES    8192
#define BYTEINCREMENT 8192
 
list<string> ReadValuefromRegister(std::string path)
{
    HKEY rKey;
    LONG result_adapt_info; //Возврат функции RegOpenKeyEx
 
    list<string> lstreg_adapt; //Список путей реестра к сетевым адаптерам
 
    DWORD BufferSize = TOTALBYTES;
    DWORD dwBufLen; //Размер буфера для Value
    DWORD dwRet; //Возврат функции RegQueryValueEx
    char* szBuf; //Буфер для Value
    szBuf = (char*)malloc(BufferSize);
    dwBufLen = BufferSize;
 
    DWORD dwtype = 0; //Тип данных из Value 
 
    list<string> str_nameValue; //Список Value для перебора
    list<string>::iterator str_Value_it; //Итератор списка Value
    string str_ip = "IPAddress";
    string str_mask = "SubnetMask";
    string str_gate = "DefaultGateway";
    string str_dns = "NameServer";
    str_nameValue.push_back(str_ip);
    str_nameValue.push_back(str_mask);
    str_nameValue.push_back(str_gate);
    str_nameValue.push_back(str_dns);
 
    string bufValueName;
    char *charValue_name = new char[bufValueName.length() + 1];
    char *path_adapt_result = new char[path.length() + 1]; //массив для передачи пути реестра в RegOpenKeyEx
    strcpy(path_adapt_result, path.c_str()); //конвертируем строку в char
 
    result_adapt_info = RegOpenKeyEx(HKEY_LOCAL_MACHINE, path_adapt_result, 0, KEY_READ, &rKey);
 
    if (result_adapt_info != ERROR_SUCCESS)
    {
        printf("Failed open key");
    }
    else
    { 
        lstreg_adapt.push_front(path_adapt_result);
        printf("\n");
        printf("Adapter:\n");
        printf(path_adapt_result);
        printf("\n");
 
        //Перебираем имена Value из списка
        for (str_Value_it = str_nameValue.begin(); str_Value_it != str_nameValue.end(); str_Value_it++)
        {
            bufValueName = *str_Value_it;
            strcpy(charValue_name, bufValueName.c_str()); //Конвертируем строку в массив
 
            dwRet = RegQueryValueEx(rKey, charValue_name,NULL, &dwtype,(LPBYTE)szBuf, &dwBufLen);
            while (dwRet == ERROR_MORE_DATA)
            {
                BufferSize += BYTEINCREMENT;
                szBuf = (char*)realloc(szBuf, BufferSize);
                dwBufLen = BufferSize;
                dwRet = RegQueryValueEx(rKey, charValue_name, NULL, &dwtype, (LPBYTE)szBuf, &dwBufLen);
            }
            if (dwRet == ERROR_SUCCESS)
            {
                printf(charValue_name);
                printf(":\n");
                printf(szBuf);
                printf("\n");
            }
            else
            {
                printf(charValue_name);
                printf(":\n");
                printf("Can't find Value\n");
            }
        }
 
    }
    free(szBuf);
    RegCloseKey(rKey);
    delete[] path_adapt_result;
    return lstreg_adapt;
}
Программа обрабатывает 2 из 3-х сетевых адаптера и вывод их значения на экран, а на обработке третьего (причем IPAddress читает, а вот при чтении значения SubnetMask и появляется эксепшн) здесь появляется исключение:
Код:
BufferSize += BYTEINCREMENT;
szBuf = (char*)realloc(szBuf, BufferSize);
В чём косяк?
Предполагаю, что где-то выход за пределы массива, но где?
Как тогда правильно выделить память для буфера?
Paul_man вне форума Ответить с цитированием
Старый 20.04.2017, 16:41   #2
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,336
По умолчанию

Цитата:
string bufValueName;
char *charValue_name = new char[bufValueName.length() + 1];
под charValue_name у тебя выделен 1 байт, а копируешь туда ты больше одного байта

и вообще, мешать malloc с new - признак говнокода.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 20.04.2017, 21:37   #3
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

...и вообще забудьте про malloc, если пишите для компилятора С++. Он потоко не безопасен, могут возникать любопытные факапы при многих потоках.
alexzk вне форума Ответить с цитированием
Старый 20.04.2017, 23:21   #4
pproger
C++ hater
СтарожилДжуниор
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,336
По умолчанию

Цитата:
Сообщение от alexzk Посмотреть сообщение
...и вообще забудьте про malloc, если пишите для компилятора С++. Он потоко не безопасен, могут возникать любопытные факапы при многих потоках.
у тебя неправильный malloc, и он дает неправильную память

Цитата:
┌─────────────────────┬──────────── ───┬─────────┐
│Interface │ Attribute │ Value │
├─────────────────────┼──────────── ───┼─────────┤
│malloc(), free(), │ Thread safety │ MT-Safe │
│calloc(), realloc() │ │ │
└─────────────────────┴──────────── ───┴─────────┘
CONFORMING TO
POSIX.1-2001, POSIX.1-2008, C89, C99.
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Старый 20.04.2017, 23:28   #5
alexzk
Форумчанин
 
Регистрация: 12.04.2017
Сообщений: 889
По умолчанию

Цитата:
Сообщение от pproger Посмотреть сообщение
у тебя неправильный malloc, и он дает неправильную память
Там зависит от либы. Да еще и от архитектур. В упомянутых посикс, помоему, арм не упомянут.
Для анроида, например, в комплекте 3 разных stdlib имплементации ...чем ото разбиратся, проще юзать new всегда.

Последний раз редактировалось alexzk; 20.04.2017 в 23:30.
alexzk вне форума Ответить с цитированием
Старый 20.04.2017, 23:35   #6
Croessmah
Вредный кошак
Участник клуба
 
Аватар для Croessmah
 
Регистрация: 14.10.2012
Сообщений: 1,159
По умолчанию

Ну и из стандарта C++
Цитата:
For purposes of determining the existence of data races, the library versions of operator new, user replacement versions of global operator new, the C standard library functions aligned_alloc, calloc, and malloc, the library versions of operator delete, user replacement versions of operator delete, the C standard library function free, and the C standard library function realloc shall not introduce a data race (20.5.5.9). Calls to these functions that allocate or deallocate a particular unit of storage shall occur in a single total order, and each such deallocation call shall happen before (4.7) the next allocation (if any) in this order.
Croessmah вне форума Ответить с цитированием
Старый 26.04.2017, 10:08   #7
Paul_man
 
Регистрация: 28.02.2012
Сообщений: 3
По умолчанию

thanks, pproger
Код:
#define MAX_VALUE_NAME 16383
char *charValue_name = new char[MAX_VALUE_NAME];
Говнокод буду исправлять.

А по поводу malloc, так это код с MSDN:
https://msdn.microsoft.com/ru-ru/lib...=vs.85%29.aspx
Paul_man вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Работа с malloc() в СИ murtukov Помощь студентам 2 30.01.2013 09:24
malloc в С++ _Kitten_ Помощь студентам 2 12.12.2011 19:20
Malloc Sabin4ik Общие вопросы C/C++ 12 18.02.2011 01:13
SIEGSEGV в malloc() TheVampire Общие вопросы C/C++ 0 25.09.2009 14:32
Проблема с malloc Обледеневший Общие вопросы C/C++ 7 14.09.2009 18:06