[C] портится память. как найти почему?
.................
int i;
double** Q;
Q=(double**) malloc(5*sizeof(double*;
for (i=0; i<5; i++)
Q[i]=(double*) malloc(4*sizeof(double;
.................
free(Q[1]); - тут вылетает ошибка! почему?
а что находится во втором многоточии? после беглого осмотра ошибка в приведенном куске не найдена
.................
int i;
double** Q;
Q=(double**) malloc(5*sizeof(double*;
for (i=0; i<5; i++)
Q[i]=(double*) malloc(4*sizeof(double;
................. <---------------------------- Здесь
free(Q[1]); - тут вылетает ошибка! почему?
А ты уверен, что в отмеченном месте не происходит записи вне
индексов выделенного массива?
---
...Я работаю антинаучным аферистом...
как перевести на русский то, что он выдаёт при ошибке (см. первый пост)?
на русский это переводится как, что ты где-то до этого запортил память.
как перевести на русский то, что он выдаёт при ошибке (см. первый пост)?Segmentation fault?
и вообще, разве можно запортить память так, чтобы программа продолжала работать?
double * q = (double*)malloc(n * sizeof(double;
double * q2 = (double*)malloc(n * sizeof(double;
for (int i = 0; i <= n; ++i)
q[i] = 0;
будет отлично работать
а падать уже будет на free q2;
выкладывай всю программу, не томи
> программа продолжала работать?
Здрасьте!
Разумеется, можно.
Про это всякие bugtraq-и пишут, как можно запортить память так,
чтобы программа продолжала работать, но не так, как предполагалось.
> странно, потому что к моменту выполнения этой
> команды Q[1] - нормальный массив, все элементы
> которого просматриваются. А никакого другого
> участка памяти эта команда вроде не должна
> касаться...
Ключевое слово --- "вроде".
---
...Я работаю антинаучным аферистом...
почему? потому что туда ничего не записали?..
кстати, в приведенном примере программа бы вылетела уже на последней стадии цикла, т.к. q[n] - незааллоченное место (там n элементов, значит максимальный индекс n-1 правильно?
ага, 450 строксделай .zip архив и зааплодь на форум. Проблема найдется на порядок быстрее, чем при текущем подходе.
нет, не правильно
место за массивом q тоже залочено, но уже под массив q2
первая мысль — в Q[1] записал какой-нибудь отстой
прикольно, сейчас посмотрю на предмет ошибок такого типа, спасибо!
Кстати, насколько необходимо вообще освобождать память в конце работы приложения?:)
Память всё равно освободится при выходе.
---
...Я работаю антинаучным аферистом...
насколько необходимо вообще освобождать память в конце работы приложения
Крайне желательно!
Так ты никогда не найдёшь выход за границы массива,
только если тебе очень повезёт.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Убери в свойствах проекта Runtime warnings нахрен, раз такой джедай и во всём уверен :-)
Хотя.. ты прав. Здесь немного другой случай
лучше освобождать, чтобы как раз было проще найти такие ошибки и утечки памяти
Один из способов найти выходы за границы массива - переписать все на вектор (если все довольно легко переписывается).
Один из способов найти выходы за границы массива - переписать все на вектор (если все довольно легко переписывается).Вроде бы тут C.
Танец с бубном:
Попробуй поменять размерности массивов, тогда программа может выпасть раньше, будет проще отладить.
Перед каждым обращением к массиву поставь проверку, что индекс не выходит за диапазон (assert тебе в помощь).
А если все-таки это С++, перепеши на std::vector
>> память в конце работы приложения?:)
> лучше освобождать, чтобы как раз было проще найти
> такие ошибки и утечки памяти
Чтобы проще было искать, надо освобождать память не в конце
работы приложения, а сразу же, как только память перестаёт
использоваться.
---
...Я работаю антинаучным аферистом...
согласен
Вопспользуйся ElectricFence или чем-нибудь аналогичным.
Нет бы посоветовать книжку по основам программирования почитать.
---
...Я работаю антинаучным аферистом...
Тогда уж лучше советовать сразу учить Lisp™
Я боюсь, что препод такое решение не оценит должным образом
---
...Я работаю антинаучным аферистом...
Чувство юмора тоже свойственно не всем форумчанам. И чо?
---
...Я работаю антинаучным аферистом...
Lisp фуднаментальнее.
---
...Я работаю антинаучным аферистом...
Спорное утверждение. Не существует такой функциональности Haskell, которую нельзя было бы реализовать на Lisp.
---
...Я работаю антинаучным аферистом...
А в Хаскеле, когда возникает необходимость, приходится это делать через неестественные абстракции.
---
...Я работаю антинаучным аферистом...
Определи функциональность.
---
"Расширь своё сознание!"
Я трактовал в значении "В противополжность ``ни на что не годится''".
Тогда lambda calculus ещё "функциональнее". В нём не то что императивно, в нём вообще почти как угодно писать тяжело.
valgrind точно поможет
кстати, в приведенном примере программа бы вылетела уже на последней стадии цикла, т.к. q[n] - незааллоченное место (там n элементов, значит максимальный индекс n-1 правильно?это логично, но, кажется, неверно (хотя я в линухе не проверял)
при выделении подобных массивов вроде как по стандарту выделяется место и под следующий за последним элемент (при этом он чаще всего ноль и вроде как я об этом у Страуструпа читал когда-то... если это не так, поправьте
посмотри какой у него тип у Q - имхо, судя по строкам его программы, он правильно удаляет то, что создал
Ключевое слово --- "вроде".
Ссылку на стандарт приведёшь?
> выделяется место и под следующий за последним элемент
> (при этом он чаще всего ноль
> и вроде как я об этом у Страуструпа читал когда-то...
А причём здесь Страуструп?
---
<<...Должны мыслить существительными и глаголами:
"он встретился", "она сказала", "он передал"...
Вы что, не допускаете мысли?..>>
я считаю всё написанное в книжке страуструпа стандартом или как минимум тем, чему стоит доверять
ты лучше скажи как линукс реагирует на обращение за последний элемент массива
> или как минимум тем, чему стоит доверять
Название книжки скажи, да?
> ты лучше скажи как линукс реагирует на обращение за последний
> элемент массива
Меня это не волнует.
---
...Я работаю антинаучным аферистом...
и вообще, зачем ты меня коментишь, если по существу ничего сказать не можешь и на мои вопросы не отвечаешь? попиздеть-то и я люблю, но зачем это делать тут?
А теперь прочитай заголовок.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
при выделении подобных массивов вроде как по стандарту выделяется место и под следующий за последним элемент (при этом он чаще всего нольне помню такого.
да, и на страуструппа это не похоже, он обычно как раз как можно меньше старался вдаваться в детали реализации.
пример:Пипец, только что нашел ошибку - я внутренний массив аллочил
.................
int i;
double** Q;
Q=(double**) malloc(5*sizeof(double*;
for (i=0; i<5; i++)
Q[i]=(double*) malloc(4*sizeof(double;
.................
free(Q[1]); - тут вылетает ошибка! почему?
Q[i]=(double*) malloc(4*sizeof(double*
Ну надо же... Как только прога работала? Ведь ятуда записывал! У double* и double что, размеры совпадают?..
ну вообще на моей 32битной машинке - нет, double - 8байт, double* - 4
Вообще-то, что-что, а такое легко проверить.
---
...Я работаю антинаучным аферистом...
тогда бы без флуда тебе указали на ошибку.
[offtopic]
int i;
double** Q;
Q=(double**) malloc(5*sizeof(double*;
for (i=0; i<5; i++)
Q[i]=(double*) malloc(4*sizeof(double;
.................
free(Q[1]);
Раз у тебя строки одной (или приблизительно одной) длины, делай так:
int i;
double* Q;
Q=(double*) malloc(5*4*sizeof(double;
.................
free(Q);
А для обращения к элементам используй Q[N(i,j)] вместо Q[i][j], где N(i,j) — функция (макрос) возвращающая либо i+j*5, либо j+i*4 (в зависимости от того, какой индекс у тебя меняется подряд — этот индекс лучше ставить без умножения). Тогда программа у тебя будет проще и ошибок в ней будет меньше, а работать она будет быстрее. А если твоя замечательная функция N(i,j) в режиме отладки ещё и проверять диапазоны будет (или хотя бы тривиальное (i+j*5)%20 делать то ошибку тебе станет найти проще, так как из класса "undefined behaviour" ты её, скорее всего, выведешь.
[/offtopic]
Оставить комментарий
velet25
В программе создаётся динамический массив динамических массивов double.В конце программы при попытке сделать free для внутренних массивов вылетает ошибка:
DAMAGE: after Normal block (#48) at 0x004401D0.
Что это значит? Что я не так делаю?:(