Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> проблема с realloc(массив), debug assertation failed 
:(
    Опции темы
DPbIH
Дата 24.10.2007, 15:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 3.4.2007

Репутация: нет
Всего: нет



Такой вот код

Код

int main( int argc, char** argv ) {
//Создаем новый массив аргументов, в котором будут ссылки на ЛКФ и ГКФ
    argv = (char**)realloc(argv, sizeof(argv) * argc + 2 * sizeof(char) );

.....................................

}


При попытке расширить массив вываливается окошко debug assertation failed
а именно не проходит следующий assert

Код

        /*
         * If this ASSERT fails, a bad pointer has been passed in. It may be
         * totally bogus, or it may have been allocated from another heap.
         * The pointer MUST come from the 'local' heap.
         */
        _ASSERTE(_CrtIsValidHeapPointer(pUserData));


pUserData - указатель на нулевой элемент массива и до попытке рэаллока он был валидный. Так какого ху? 
Спасибо за ответы,товарищи проггеры!
PM MAIL   Вверх
Fazil6
Дата 24.10.2007, 15:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: нет
Всего: 60



Цитата(DPbIH @  24.10.2007,  15:15 Найти цитируемый пост)
pUserData - указатель на нулевой элемент массива и до попытке рэаллока он был валидный. Так какого ху? 

прикольно...
С чего ты взял, что это должно работать? argv это не HeapPointer
PM MAIL   Вверх
zkv
Дата 24.10.2007, 16:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(Fazil6 @  24.10.2007,  15:58 Найти цитируемый пост)
С чего ты взял

уровень преподавания языка такой :( 
Я помню нечто подобное пытался провернуть когда-то, 
показывал преподу (преподавательнице вернее), та разводила руками, типа хз.  smile
PM MAIL   Вверх
NiJazz
Дата 25.10.2007, 08:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


Профиль
Группа: Экс. модератор
Сообщений: 2286
Регистрация: 10.8.2003
Где: Москва

Репутация: 6
Всего: 23



DPbIH, realloc вызывается в DLL? В таком случае, видимо, память изначально была выделена в самом exe и передана в DLL по указателю. 
Я не помню точно где, но бытует утверждение, что realloc использовать не нужно. Извини, но объективно объяснить не могу, так как сам не пользуюсь CRT для работы с массивами и буферами вообще. Если нужно изменить размер буфера, обычно явно выделяют новый блок памяти, копируют туда содержимое старого буфера, затем старый буфер удаляют. Теоретически, realloc делает то же самое. smile 
Ты не смотрел в сторону STL?
PM MAIL   Вверх
zkv
Дата 25.10.2007, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



1. объявление немного некорректное:
Цитата(DPbIH @  24.10.2007,  15:15 Найти цитируемый пост)
int main( int argc, char** argv )

на самом деле должно быть:
Код

int main( int argc, char* argv[] )

как говорится почувствуйте разницу smile

2. пусть даже char** argv, что это значит? 
Что у нас имеется динамический массив указателей на непрерывные участки в памяти, притом никто не обещает что они непрерывно будут следовать друг за другом, а realloc работает с memory block.
Это хорошо еще, что компилер хоть assert'ом по руками ударил. 
Цитата(DPbIH @  24.10.2007,  15:15 Найти цитируемый пост)
Так какого ху? 

вот такого  smile 
PM MAIL   Вверх
DPbIH
Дата 25.10.2007, 11:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 3.4.2007

Репутация: нет
Всего: нет



Цитата(NiJazz @ 25.10.2007,  08:10)
DPbIH, realloc вызывается в DLL? В таком случае, видимо, память изначально была выделена в самом exe и передана в DLL по указателю. 
Я не помню точно где, но бытует утверждение, что realloc использовать не нужно. Извини, но объективно объяснить не могу, так как сам не пользуюсь CRT для работы с массивами и буферами вообще. Если нужно изменить размер буфера, обычно явно выделяют новый блок памяти, копируют туда содержимое старого буфера, затем старый буфер удаляют. Теоретически, realloc делает то же самое. smile 
Ты не смотрел в сторону STL?

нет, не в DLL.
Мне нужно создать массив, указывая размер через переменную.
Вектор не катит, потому, что дальше этот масси мне нужно передать в функцию, которую писал не я, и которую переписывать нельзя.
PM MAIL   Вверх
zkv
Дата 25.10.2007, 11:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(DPbIH @  25.10.2007,  11:50 Найти цитируемый пост)
Мне нужно создать массив, указывая размер через переменную.

так заведи собственные переменные и работай с ними, кто мешает?
PM MAIL   Вверх
DPbIH
Дата 25.10.2007, 12:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 3.4.2007

Репутация: нет
Всего: нет



сейчас сделал немного по-другому. Создал новый массив, а потом realloc"ом  попытался задать ему нужный размер

Код

int main( int argc, char** argv ) {
    //Создаем новый массив аргументов, в котором будут ссылки на ЛКФ и ГКФ
    char** newArgv = new char*[0];
    char**res = NULL;
    int newArgc = argc + 2;
    res = (char**)realloc(newArgv, sizeof(newArgv) * newArgc );
    
    newArgv[0] = argv[0];//ссылка на exe-файл
    newArgv[1] = strcat(getenv("W_HOME"), GCF_FILE_NAME);//ссылка на ГКФ
    newArgv[2] = strcat(getenv("W_HOME"), LCF_FILE_NAME);//ссылка на ЛКФ
    for(int i = 1; i < argc; i++)
        newArgv[i + 2] = argv[i];//остальное в конец массива

    for(int i = 0; i < newArgc; i++)
    {
        QMessageBox::warning(0, "", newArgv[i]);
    }

                WInjectMakerApp app( APP_NAME, newArgc, newArgv );


а вот результат меня удивил!!! 
в результате выполнения следующего кода

Код

for(int i = 0; i < newArgc; i++)
    {
        QMessageBox::warning(0, "", newArgv[i]);//просто посмотреть
    }


получаю

"Windows has triggered a breakpoint in winjectmaker.exe.

This may be due to a corruption of the heap, and indicates a bug in winjectmaker.exe or any of the DLLs it has loaded.

The output window may have more diagnostic information"

А вот в окне "WATCH" при просмотре элементов массива, все нормально! 

newArgv[0]    0x3a1f3830 "d:\3w\bin\winjectmaker.exe"                                                                                    char *
newArgv[1]    0x008b42af "D:\3w\app\winjectmaker\config\w.xml"                                                                    char *
newArgv[2]    0x008b42af "D:\3w\app\winjectmaker\config\winjectmaker.xml"                                                    char *
newArgv[3]    0x008b6450 "d:\3w\app\winjectmaker\config\rtdbsave.xml"                                                                    char *
newArgv[4]    0x008b647b "d:\3w\app\winjectmaker\config\out.xml"                                                                    char *


PM MAIL   Вверх
zkv
Дата 25.10.2007, 12:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(DPbIH @  25.10.2007,  11:50 Найти цитируемый пост)
Вектор не катит, потому, что дальше этот масси мне нужно передать в функцию, которую писал не я, и которую переписывать нельзя. 

по поводу передачи вектора, можно воспользоваться тем, что элементы в нем обязаны храниться непрерывно:
Код

#include <vector>
#include <iostream>

static void Print( std::ostream &stream, const char *str );

int main( int argc, char*argv[])
{
    size_t size = strlen( argv[0] );
    std::vector<char> exeName( &argv[0][0],  &argv[0][size+1] );
    Print( std::cout, &exeName[0] );

    std::cin.get();
}

void Print( std::ostream &stream, const char *str )
{
    stream<<str;
}


Добавлено через 6 минут и 27 секунд
Цитата(DPbIH @  25.10.2007,  12:03 Найти цитируемый пост)
res = (char**)realloc(newArgv, sizeof(newArgv) * newArgc );

ты понимаешь, что делаешь?
sizeof(newArgv) == 4 (наверняка, зависит от платформы)
newArgc - колличество аргументов в ком.строке плюс 2
мы все это перемножаем, и получаем колличество байт, которые надо выделить?  smile
PM MAIL   Вверх
Lazin
Дата 25.10.2007, 12:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3820
Регистрация: 11.12.2006
Где: paranoid oil empi re

Репутация: 8
Всего: 154



Цитата(DPbIH @  25.10.2007,  12:03 Найти цитируемый пост)
char** newArgv = new char*[0];
***************
    res = (char**)realloc(newArgv, sizeof(newArgv) * newArgc );

Вот так лучше не делать, ты сначала выделяешь блок памяти через new, а потом передаешь его в realloc. В место new нужно вызывать malloc или realloc с параметром NULL.

Добавлено через 1 минуту и 27 секунд
а освобождать его free
PM MAIL Skype GTalk   Вверх
Fazil6
Дата 25.10.2007, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1653
Регистрация: 3.5.2006
Где: Минск

Репутация: нет
Всего: 60



Цитата(DPbIH @  25.10.2007,  12:03 Найти цитируемый пост)
сейчас сделал немного по-другому. Создал новый массив, а потом realloc"ом  попытался задать ему нужный размер

капец просто... Ошибка в каждой строке
Код

int main( int argc, char *argv[] ) {
    //Создаем новый массив аргументов, в котором будут ссылки на ЛКФ и ГКФ
    int newArgc = argc + 2;
    char** newArgv = new char*[newArgc];
    
    newArgv[0] = argv[0];//ссылка на exe-файл
    newArgv[1] = strcat(getenv("W_HOME"), GCF_FILE_NAME);//ссылка на ГКФ
    newArgv[2] = strcat(getenv("W_HOME"), LCF_FILE_NAME);//ссылка на ЛКФ
    
    for(int i = 1; i < argc; ++i)
        newArgv[i + 2] = argv[i];//остальное в конец массива

    for(int i = 0; i < newArgc; ++i)
    {
        QMessageBox::warning(0, "", newArgv[i]);
    }

     WInjectMakerApp app( APP_NAME, newArgc, newArgv );




Это сообщение отредактировал(а) Fazil6 - 25.10.2007, 12:34
PM MAIL   Вверх
DPbIH
Дата 25.10.2007, 13:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 3.4.2007

Репутация: нет
Всего: нет



Цитата(zkv @ 25.10.2007,  12:07)
Цитата(DPbIH @  25.10.2007,  11:50 Найти цитируемый пост)
Вектор не катит, потому, что дальше этот масси мне нужно передать в функцию, которую писал не я, и которую переписывать нельзя. 

по поводу передачи вектора, можно воспользоваться тем, что элементы в нем обязаны храниться непрерывно:
Код

#include <vector>
#include <iostream>

static void Print( std::ostream &stream, const char *str );

int main( int argc, char*argv[])
{
    size_t size = strlen( argv[0] );
    std::vector<char> exeName( &argv[0][0],  &argv[0][size+1] );
    Print( std::cout, &exeName[0] );

    std::cin.get();
}

void Print( std::ostream &stream, const char *str )
{
    stream<<str;
}


Добавлено @ 12:13
Цитата(DPbIH @  25.10.2007,  12:03 Найти цитируемый пост)
res = (char**)realloc(newArgv, sizeof(newArgv) * newArgc );

ты понимаешь, что делаешь?
sizeof(newArgv) == 4 (наверняка, зависит от платформы)
newArgc - колличество аргументов в ком.строке плюс 2
мы все это перемножаем, и получаем колличество байт, которые надо выделить?  smile

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

Добавлено @ 13:20
Цитата(Lazin @ 25.10.2007,  12:18)
Цитата(DPbIH @  25.10.2007,  12:03 Найти цитируемый пост)
char** newArgv = new char*[0];
***************
    res = (char**)realloc(newArgv, sizeof(newArgv) * newArgc );

Вот так лучше не делать, ты сначала выделяешь блок памяти через new, а потом передаешь его в realloc. В место new нужно вызывать malloc или realloc с параметром NULL.

Добавлено @ 12:20
а освобождать его free

почему? new = malloc + конструктор.

Добавлено @ 13:24
2Fazil6

Код

char** newArgv = new char*[newArgc];


Реально не знал, что такое прокатывает!!!! smile  Думал, что размер нужно задавать константой. Поэтому и юзаю realloc!!!


Это сообщение отредактировал(а) DPbIH - 25.10.2007, 13:27
PM MAIL   Вверх
zkv
Дата 25.10.2007, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата



****


Профиль
Группа: Участник Клуба
Сообщений: 2133
Регистрация: 23.7.2006
Где: Санкт-Петербург

Репутация: 12
Всего: 92



Цитата(DPbIH @  25.10.2007,  13:16 Найти цитируемый пост)
все правильно, не пойму в чем проблема!

а я сразу не понял что ты там пытаешься сделать, зачем тогда new был? 
Запутать хотел? Получилось!  smile

Добавлено через 6 минут и 44 секунды
Цитата(DPbIH @  25.10.2007,  13:16 Найти цитируемый пост)
Думал, что размер нужно задавать константой.

а нафиг бы он нужен был такой new smile 
PM MAIL   Вверх
DPbIH
Дата 25.10.2007, 13:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 17
Регистрация: 3.4.2007

Репутация: нет
Всего: нет



Цитата(zkv @ 25.10.2007,  13:47)
Цитата(DPbIH @  25.10.2007,  13:16 Найти цитируемый пост)
все правильно, не пойму в чем проблема!

а я сразу не понял что ты там пытаешься сделать, зачем тогда new был? 
Запутать хотел? Получилось!  smile

Добавлено @ 13:53
Цитата(DPbIH @  25.10.2007,  13:16 Найти цитируемый пост)
Думал, что размер нужно задавать константой.

а нафиг бы он нужен был такой new smile

капец йа креведко! smile  2-й день сижу!
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0609 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.