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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> порблемы с динамикой масивов, тройной указатель и работа с ним 
:(
    Опции темы
ktototam
Дата 14.7.2006, 16:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Работаю с памятью через new(хотелось бы так и продолжать).
Массив при необходимости дополняется.
Проблема в том что при работе происходит 'сбитие' указателя (как мне кажется) , но в разных местах
сначала сбивалось при записи 8 строчки, после я закоментив пробдемную функцию таким же методом заполнял всю доступную память (доходило почти до 16 м, кстати как сделать больше?), после чего
прблема сместилась на 23 строчку.
видел пост _hunter про  IsBadWritePtr/IsBadReadPtr , но не очень понял как с ними работать(неужели  все new придётся проверять при каждом чтении и записи smile )
 - пишет: Unhandled exception in 123.exe: 0xC0000005: Access violation
 - пишу на Visual C++ 6.0
 - указатель обьявлен глобально и при обьявлении приравнен 0
 - памать выделяю следующим образом:
   UN = new char**[KOL_ROWS];
      for(int k=0;k<=KOL_ROWS;k++){UN[k] = new char*[KOL_COLM];
      for(n=0;n<=KOL_COLM;n++){UN[k][n] = new char[LEN];}}
   //KOL_ROWS - число строк
   //KOL_COLM - число столбцов
   //LEN - максимальная длинна записи
   //UN  обьявлен как char ***UN=0;

за ранее спасибо!
 
PM MAIL   Вверх
Earnest
Дата 14.7.2006, 17:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(ktototam @  14.7.2006,  17:00 Найти цитируемый пост)
Массив при необходимости дополняется.

Цитата(ktototam @  14.7.2006,  17:00 Найти цитируемый пост)
при работе происходит 'сбитие' указателя (как мне кажется) 

Что это значит? Память может только перераспределяться, при этом указатель на блок памяти вполне может измениться. Покажи код, которым ты "при необходимости дополняешь" массив. 
И  код, который пишет в эти переменные. Из того факта, что у тебя что-то там сбивается то на 8 строке, то на 23, сложно сделать осмысленный вывод. smile 
Выпавший exception явно говорит о том, что ты влез в чужой блок.
Из того, что при закомментированной функции программа не падала, не следует, что проблем с памятью нет.
 


--------------------
...
PM   Вверх
ktototam
Дата 14.7.2006, 18:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Дополнение делаю следующим образом
если например было
Код

UN = new char**[KOL_ROWS];
    for(int k=0;k<=KOL_ROWS;k++){UN[k] = new char*[KOL_COLM];
      for(n=0;n<=KOL_COLM;n++){UN[k][n] = new char[LEN];}}

и надо дописать ещё одну строку, то
Код

UN[KOL_ROWS+1] = new char*[KOL_COLM];
  for(k=0;k<=KOL_COLM;k++)}{UN[KOL_ROWS+1][k] = new char[LEN];}


запись делаю с помощью sprintf

exception происходит при new (тех самых 8 или 23 сторках например)
 
PM MAIL   Вверх
ultra
Дата 15.7.2006, 00:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(ktototam @ 14.7.2006,  18:50)
Дополнение делаю следующим образом
если например было
Код

UN = new char**[KOL_ROWS];
    for(int k=0;k<=KOL_ROWS;k++){UN[k] = new char*[KOL_COLM];
      for(n=0;n<=KOL_COLM;n++){UN[k][n] = new char[LEN];}}

ты перед циклом выделяешь память на KOL_ROWS, а в цикле последний елемент будет KOL_ROWS+1. Из-за этого и проблемы.

Вот так надо:
Код

UN = new char**[KOL_ROWS];
    for(int k=0;k<KOL_ROWS;k++){UN[k] = new char*[KOL_COLM];
      for(n=0;n<KOL_COLM;n++){UN[k][n] = new char[LEN];}}
 
PM MAIL   Вверх
ktototam
Дата 15.7.2006, 17:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Наверно ultra прав, но проверить это я смогу только в понедельник
и почему тогда 
Цитата

после я закоментив пробдемную функцию таким же методом заполнял всю доступную память (доходило почти до 16 м, кстати как сделать больше?)
 
PM MAIL   Вверх
Earnest
Дата 17.7.2006, 07:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



indeterminate behavior: C не обещает, что программа свалится сразу после ошибки.

ultra, конечно, прав: ты не имеешь права обращаться не только к элементу KOL_ROWS+1, но и к KOL_ROWS: индексация начинается с 0, так что последний элемент - KOL_ROWS-1.
Расширение массива требует 3 шагов: выделение нового блока нужного размера, копирование туда данных из старого, освобождения старого блока.
Пользовался бы ты вектором... std::vector 


--------------------
...
PM   Вверх
ktototam
Дата 17.7.2006, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



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

KOL_COLM = t;    //получаю количество столбцов от 1
UN = new char**[1];    //создаю строку для заголовков (нулевая строка)
  UN[0] = new char*[KOL_COLM];
  for(int k=0;k<KOL_COLM;k++){UN[0][k]=new char[LEN]; sprintf(UN[0][k],"%s",str);}

//когда заголовки записаны начинаю получать данные

KOL_ROWS=1;
while(1){
  . . .   //плучаю данные в двойной массив чаров если не выходит то break
  UN[KOL_ROWS] = new char*[KOL_COLM];
    for(int i=0;i<KOL_COLM;i++){UN[KOL_ROWS][i] = new char[LEN];}
  for(int n=0; n<KOL_COLM;n++){sprintf(UN[KOL_ROWS][i],"%s",str[i]);}
  KOL_ROWS++;
}

и всётаки почему
Цитата

после я закоментив проблемную функцию таким же методом заполнял всю доступную память (доходило почти до 16 м, кстати как сделать больше?)

и прекрасно работало 
может всётаки можно добавлять записи не переписывая массив (например используя IsBadWritePtr/IsBadReadPtr) 

Это сообщение отредактировал(а) ktototam - 17.7.2006, 10:43
PM MAIL   Вверх
NiJazz
Дата 17.7.2006, 11:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Jazz coder
****


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

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



ktototam, ты же на C++ пишешь? Почему б STL не использовать? Или самому написать класс для массивов, чтобы память выделялась в конструкторе и убивалась деструктором автоматически? Сразу ошибок станет меньше.
Прошу прощения, что не по теме.  

Это сообщение отредактировал(а) NiJazz - 17.7.2006, 11:24
PM MAIL   Вверх
ktototam
Дата 19.7.2006, 08:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Спасибо, но 
Цитата

Работаю с памятью через new(хотелось бы так и продолжать).

и кто знает как выделить компилятору памяти больше чем 16 м? 
PM MAIL   Вверх
Damarus
Дата 21.7.2006, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Awaiting Authorisation
Сообщений: 671
Регистрация: 6.5.2006

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



Цитата(ktototam @  19.7.2006,  09:06 Найти цитируемый пост)
кто знает как выделить компилятору памяти больше чем 16 м?


Также  smile 

Код
    
// Вот выделение 64 Mb.
unsigned char *pData = new unsigned char[0x04000000];

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

delete[] pData;

 
PM MAIL ICQ Jabber   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.0644 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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