[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]); - тут вылетает ошибка! почему?
а что находится во втором многоточии? после беглого осмотра ошибка в приведенном куске не найдена
.................
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]); - тут вылетает ошибка! почему?
А ты уверен, что в отмеченном месте не происходит записи вне
индексов выделенного массива?
---
...Я работаю антинаучным аферистом...
уверен... ошибка происходит именно на шаге free.
как перевести на русский то, что он выдаёт при ошибке (см. первый пост)?
как перевести на русский то, что он выдаёт при ошибке (см. первый пост)?
> как перевести на русский то, что он выдаёт при ошибке (см. первый пост)?
на русский это переводится как, что ты где-то до этого запортил память.
на русский это переводится как, что ты где-то до этого запортил память.
как перевести на русский то, что он выдаёт при ошибке (см. первый пост)?Segmentation fault?

странно, потому что к моменту выполнения этой команды Q[1] - нормальный массив, все элементы которого просматриваются. А никакого другого участка памяти эта команда вроде не должна касаться...
и вообще, разве можно запортить память так, чтобы программа продолжала работать?
и вообще, разве можно запортить память так, чтобы программа продолжала работать?
какой-нибудь такой кусок
будет отлично работать
а падать уже будет на free q2;
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] - нормальный массив, все элементы
> которого просматриваются. А никакого другого
> участка памяти эта команда вроде не должна
> касаться...
Ключевое слово --- "вроде".
---
...Я работаю антинаучным аферистом...
> программа продолжала работать?
Здрасьте!
Разумеется, можно.
Про это всякие bugtraq-и пишут, как можно запортить память так,
чтобы программа продолжала работать, но не так, как предполагалось.
> странно, потому что к моменту выполнения этой
> команды Q[1] - нормальный массив, все элементы
> которого просматриваются. А никакого другого
> участка памяти эта команда вроде не должна
> касаться...
Ключевое слово --- "вроде".
---
...Я работаю антинаучным аферистом...
почему? потому что туда ничего не записали?..
ага, 450 строк
кстати, в приведенном примере программа бы вылетела уже на последней стадии цикла, т.к. q[n] - незааллоченное место (там n элементов, значит максимальный индекс n-1 правильно?
кстати, в приведенном примере программа бы вылетела уже на последней стадии цикла, т.к. q[n] - незааллоченное место (там n элементов, значит максимальный индекс n-1 правильно?
ага, 450 строксделай .zip архив и зааплодь на форум. Проблема найдется на порядок быстрее, чем при текущем подходе.
> правильно?
нет, не правильно
место за массивом q тоже залочено, но уже под массив q2
нет, не правильно
место за массивом q тоже залочено, но уже под массив q2
первая мысль — в Q[1] записал какой-нибудь отстой
прикольно, сейчас посмотрю на предмет ошибок такого типа, спасибо!
Кстати, насколько необходимо вообще освобождать память в конце работы приложения?:)
Нисколько.
Память всё равно освободится при выходе.
---
...Я работаю антинаучным аферистом...
Память всё равно освободится при выходе.
---
...Я работаю антинаучным аферистом...
насколько необходимо вообще освобождать память в конце работы приложения
Крайне желательно!
Идиотская подсказка.
Так ты никогда не найдёшь выход за границы массива,
только если тебе очень повезёт.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Так ты никогда не найдёшь выход за границы массива,
только если тебе очень повезёт.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
Убери в свойствах проекта Runtime warnings нахрен, раз такой джедай и во всём уверен :-)
Хотя.. ты прав. Здесь немного другой случай 

> Кстати, насколько необходимо вообще освобождать память в конце работы приложения?:)
лучше освобождать, чтобы как раз было проще найти такие ошибки и утечки памяти
лучше освобождать, чтобы как раз было проще найти такие ошибки и утечки памяти
Один из способов найти выходы за границы массива - переписать все на вектор (если все довольно легко переписывается).
Один из способов найти выходы за границы массива - переписать все на вектор (если все довольно легко переписывается).Вроде бы тут C.
Как тут уже тебе писали, ошибка почти точно в том, что ты выходишь за границы массива, так что падение программы — не проблема, а следствие проблемы (ошибки где-то раньше).
Танец с бубном:
Попробуй поменять размерности массивов, тогда программа может выпасть раньше, будет проще отладить.
Перед каждым обращением к массиву поставь проверку, что индекс не выходит за диапазон (assert тебе в помощь).
А если все-таки это С++, перепеши на std::vector
Танец с бубном:
Попробуй поменять размерности массивов, тогда программа может выпасть раньше, будет проще отладить.
Перед каждым обращением к массиву поставь проверку, что индекс не выходит за диапазон (assert тебе в помощь).
А если все-таки это С++, перепеши на std::vector
>> Кстати, насколько необходимо вообще освобождать
>> память в конце работы приложения?:)
> лучше освобождать, чтобы как раз было проще найти
> такие ошибки и утечки памяти
Чтобы проще было искать, надо освобождать память не в конце
работы приложения, а сразу же, как только память перестаёт
использоваться.
---
...Я работаю антинаучным аферистом...
>> память в конце работы приложения?:)
> лучше освобождать, чтобы как раз было проще найти
> такие ошибки и утечки памяти
Чтобы проще было искать, надо освобождать память не в конце
работы приложения, а сразу же, как только память перестаёт
использоваться.
---
...Я работаю антинаучным аферистом...
согласен
Вопспользуйся ElectricFence или чем-нибудь аналогичным.
> Вопспользуйся ElectricFence или чем-нибудь аналогичным.
Нет бы посоветовать книжку по основам программирования почитать.
Нет бы посоветовать книжку по основам программирования почитать.
Ты не читал Ерсуб "про математиков"?
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
Тогда уж лучше советовать сразу учить Lisp™
Я боюсь, что препод такое решение не оценит должным образом 

Lisp не является товарным знаком.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
Чувство юмора тоже свойственно не всем форумчанам. И чо?
Хаскелл популярнее.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
Lisp фуднаментальнее.
Haskell функциональнее.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
Спорное утверждение. Не существует такой функциональности Haskell, которую нельзя было бы реализовать на Lisp.
В лиспе слишком просто писать императивно.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
А в Хаскеле, когда возникает необходимость, приходится это делать через неестественные абстракции.
Верно. Поэтому хаскелл функциональнее.
---
...Я работаю антинаучным аферистом...
---
...Я работаю антинаучным аферистом...
Определи функциональность.
В противоположность "императивнее".
---
"Расширь своё сознание!"
---
"Расширь своё сознание!"
Я трактовал в значении "В противополжность ``ни на что не годится''".
Тогда lambda calculus ещё "функциональнее". В нём не то что императивно, в нём вообще почти как угодно писать тяжело.
valgrind точно поможет
кстати, в приведенном примере программа бы вылетела уже на последней стадии цикла, т.к. q[n] - незааллоченное место (там n элементов, значит максимальный индекс n-1 правильно?это логично, но, кажется, неверно (хотя я в линухе не проверял)
при выделении подобных массивов вроде как по стандарту выделяется место и под следующий за последним элемент (при этом он чаще всего ноль и вроде как я об этом у Страуструпа читал когда-то... если это не так, поправьте
посмотри какой у него тип у Q - имхо, судя по строкам его программы, он правильно удаляет то, что создал
> при выделении подобных массивов вроде как по стандарту
Ключевое слово --- "вроде".
Ссылку на стандарт приведёшь?
> выделяется место и под следующий за последним элемент
> (при этом он чаще всего ноль
> и вроде как я об этом у Страуструпа читал когда-то...
А причём здесь Страуструп?
---
<<...Должны мыслить существительными и глаголами:
"он встретился", "она сказала", "он передал"...
Вы что, не допускаете мысли?..>>
Ключевое слово --- "вроде".
Ссылку на стандарт приведёшь?
> выделяется место и под следующий за последним элемент
> (при этом он чаще всего ноль
> и вроде как я об этом у Страуструпа читал когда-то...
А причём здесь Страуструп?
---
<<...Должны мыслить существительными и глаголами:
"он встретился", "она сказала", "он передал"...
Вы что, не допускаете мысли?..>>
ты мне будешь указывать где у меня ключевые слова? тебе нравится игра "найди Х" (прямо из анекдота)? 
я считаю всё написанное в книжке страуструпа стандартом или как минимум тем, чему стоит доверять
ты лучше скажи как линукс реагирует на обращение за последний элемент массива

я считаю всё написанное в книжке страуструпа стандартом или как минимум тем, чему стоит доверять
ты лучше скажи как линукс реагирует на обращение за последний элемент массива
> я считаю всё написанное в книжке страуструпа стандартом
> или как минимум тем, чему стоит доверять
Название книжки скажи, да?
> ты лучше скажи как линукс реагирует на обращение за последний
> элемент массива
Меня это не волнует.
---
...Я работаю антинаучным аферистом...
> или как минимум тем, чему стоит доверять
Название книжки скажи, да?
> ты лучше скажи как линукс реагирует на обращение за последний
> элемент массива
Меня это не волнует.
---
...Я работаю антинаучным аферистом...
Язык программирования C++. Ed. 3
и вообще, зачем ты меня коментишь, если по существу ничего сказать не можешь и на мои вопросы не отвечаешь? попиздеть-то и я люблю, но зачем это делать тут?
и вообще, зачем ты меня коментишь, если по существу ничего сказать не можешь и на мои вопросы не отвечаешь? попиздеть-то и я люблю, но зачем это делать тут?
> Язык программирования C++. Ed. 3
А теперь прочитай заголовок.
---
"Vyroba umelych lidi, slecno, je tovarni tajemstvi."
А теперь прочитай заголовок.
---
"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
> У double* и double что, размеры совпадают?..
Вообще-то, что-что, а такое легко проверить.
---
...Я работаю антинаучным аферистом...
Вообще-то, что-что, а такое легко проверить.
---
...Я работаю антинаучным аферистом...
код надо было правильно копировать (причем полностью, а не кусками).
тогда бы без флуда тебе указали на ошибку.
тогда бы без флуда тебе указали на ошибку.
По вопросу: используй malloc debugger (например, valgrind).
[offtopic]
Раз у тебя строки одной (или приблизительно одной) длины, делай так:
А для обращения к элементам используй 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]
[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.
Что это значит? Что я не так делаю?:(