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

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

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

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 03.12.2014, 23:46   #1
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 138
По умолчанию Ошибка при вызове free()

Доброго времени суток, пишу программу решения обычного симплекс-метода.

При вызове free() происходит ошибка в памяти

Код:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct
{
unsigned char m,n;//количество строк, столбцов
unsigned char *ogranich;//знаки ограничений (0 - = | 1 - <= | 2 - >=)
unsigned char strem;//знак стремления функции (0 - min | 1 - max)
double *celfun;//коэффициенты целевой функции
double **mas;//матрица коэффициентов	
unsigned char error;//код ошибки	
}simplex;


void rightnotminus(double *vector,unsigned char size,unsigned char *ogranich)
{//вызов в случае отрицательного свободного члена
	//меняем знаки коэффициентов и ограничений на противоположные
int i;	
for(i=0;i<size;i++)	vector[i]=-vector[i];
if(*ogranich==1) *ogranich=2;
else if(*ogranich==2) *ogranich=1;
}

void add_element(double **mas,unsigned char m,unsigned char *n,int d)//d - позиция вставки, зак минуса указывает на кээффицент перед элементом
{// в этой функции ошибка, связанная с распределением динамической памяти
int i,j;	
double *p;



for(i=0;i<m;i++)
{	
p=(double *)malloc((*n + 1) * sizeof(double));	
	
for(j=0;j<*n;j++)
p[j]=mas[i][j];// присваиваем коэффициенты (до свободного члена)

if(i==d-1) p[j]=(int) (d/fabs(d)); // 1 или -1	
else p[j]=0;

p[j+1]=mas[i][j];// свободный член

//free(mas[i]); //при откомменчивании появляюется ошибка
mas[i]=p;
//free(p); //при откомменчивании появляюется ошибка

}

(*n)++;// увеличиваем количество столбцов в матрице
	
}


void program(simplex aa)
{
int i,j;	

for(i=0;i<aa.m;i++)//выполняем проверку на отрицательность свободных членов
if(aa.mas[i][aa.n]<0) rightnotminus(aa.mas[i],aa.n+1,&aa.ogranich[i]);

for(i=0;i<aa.m;i++,printf("%i\n",aa.ogranich[i-1]))
for(j=0;j<=aa.n;j++) printf("%f\t",aa.mas[i][j]);
	
	
printf("\n");	
	
for(i=0;i<aa.m;i++)	// в случае <= добавляем вектор с 1 и нулями
//в случае >= добавляем вектор с 1 и нулями
if(aa.ogranich[i]==1)	add_element(aa.mas,aa.m,&aa.n,i+1);
else if(aa.ogranich[i]==2)	add_element(aa.mas,aa.m,&aa.n,-(i+1));
	
	
printf("\n\n");
for(i=0;i<aa.m;i++,printf("%i\n",aa.ogranich[i-1]))
for(j=0;j<=aa.n;j++) printf("%f\t",aa.mas[i][j]);
	
}




int main()
{
int i,j;	
/*
Пример
F = -2x1 + 5x2 -3x3 -> min 
-6x1 + 4x2 - 2x3 <=2
 4x1 + 3x2 + 9x3 <=1
  x1 + 3x2 - 5x3 <=4  
*/	
simplex sm;	
sm.m=3;
sm.n=3;

sm.celfun = (double *)malloc((sm.n + 1) * sizeof(double));
sm.celfun[0]=-2;
sm.celfun[1]=5;
sm.celfun[2]=-3;
sm.celfun[4]=0;
sm.strem=0;//min

for(i=0;i<=sm.n;i++)
printf("%f\t",sm.celfun[i]);
printf("\n\n");

sm.mas = (double**)malloc(sm.m * sizeof(double*));
for(i=0;i<sm.m;i++)
sm.mas[i]=(double *)malloc((sm.n + 1) * sizeof(double));

sm.mas[0][0]=+6;
sm.mas[0][1]=-4;
sm.mas[0][2]=+2;
sm.mas[0][3]=-2;

sm.mas[1][0]=4;
sm.mas[1][1]=3;
sm.mas[1][2]=9;
sm.mas[1][3]=1;

sm.mas[2][0]=-1;
sm.mas[2][1]=-3;
sm.mas[2][2]=+5;
sm.mas[2][3]=-4;


sm.ogranich=(unsigned char *)malloc(sm.m * sizeof(unsigned char));
sm.ogranich[0]=2;//<=
sm.ogranich[1]=1;//<=
sm.ogranich[2]=2;//<=


for(i=0;i<sm.m;i++,printf("%i\n",sm.ogranich[i-1]))
for(j=0;j<=sm.n;j++) printf("%f\t",sm.mas[i][j]);
printf("\n");

program(sm);

	return 0;
	}
При free(mas[i]);
Код:
*** Error in `./project': double free or corruption (out): 0x0000000000603090 ***
======= Backtrace: =========
/lib64/libc.so.6(+0x7af96)[0x7f5d27c71f96]
/lib64/libc.so.6(+0x7be73)[0x7f5d27c72e73]
./project[0x400839]
./project[0x4009dc]
./project[0x400e38]
/lib64/libc.so.6(__libc_start_main+0xf5)[0x7f5d27c18ad5]
./project[0x400589]
======= Memory map: ========
здесь много всякой информации
Аварийный останов
При *** Error in `./project': free(): invalid next size (fast): 0x0000000000603110 ***
project: malloc.c:2371: sysmalloc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof(size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' failed.
Аварийный останов

При закомменчивании освобождений памяти программа не ругается, но на третьем шаге свободные члены становятся равными нулю.

В чём у меня ошибка?
ivan.tiran вне форума Ответить с цитированием
Старый 04.12.2014, 07:58   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Глупый вопрос: А зачем освобождать именно в том цикле? Почему бы не в конце программы?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 04.12.2014, 09:07   #3
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,342
По умолчанию

Я не особо внимательно смотрел, но не совсем понятна такая логика:
mas[i] = p;
free(p);


Далее, чему будет равно содержание mas[0][0] после этой строки:
sm.mas[0][0]=+6;
К памяти это не относится, но все же...
waleri вне форума Ответить с цитированием
Старый 04.12.2014, 20:59   #4
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 138
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
Глупый вопрос: А зачем освобождать именно в том цикле? Почему бы не в конце программы?
сейчас до меня дошло, что p освобождать не надо. Иначе, у mas[i] ничего не будет. Но по-прежнему не могу освободить mas[i] перед присвоением p.
ivan.tiran вне форума Ответить с цитированием
Старый 04.12.2014, 21:31   #5
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 138
По умолчанию

Теперь работает:

Код:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

typedef struct
{
unsigned char m,n;//количество строк, столбцов
unsigned char *ogranich;//знаки ограничений (0 - = | 1 - <= | 2 - >=)
unsigned char strem;//знак стремления функции (0 - min | 1 - max)
double *celfun;//коэффициенты целевой функции
double **mas;//матрица коэффициентов	
unsigned char error;//код ошибки	
}simplex;


void rightnotminus(double *vector,unsigned char size,unsigned char *ogranich)
{//вызов в случае отрицательного свободного члена
	//меняем знаки коэффициентов и ограничений на противоположные
int i;	
for(i=0;i<size;i++)	vector[i]=-vector[i];
if(*ogranich==1) *ogranich=2;
else if(*ogranich==2) *ogranich=1;
}



double *past_in_vector(double *vector,unsigned char size,unsigned char poz,double element)
{
double *p;	
int i;
p=(double *)malloc((size + 1) * sizeof(double));

for(i=0;i<poz;i++)	
p[i]=vector[i];	
p[i]=element;	
for(i=poz;i<size;i++)	
p[i+1]=vector[i];	

free(vector);
	
return p;	
	}


void add_element(double **mas,unsigned char m,unsigned char *n,int d)//d - позиция вставки, зак минуса указывает на кээффицент перед элементом
{// в этой функции ошибка, связанная с распределением динамической памяти
int i;	


for(i=0;i<m;i++)
if(i==abs(d)-1) mas[i]=past_in_vector(mas[i],*n+1,*n,d/abs(d)); // 1 или -1	
else mas[i]=past_in_vector(mas[i],*n+1,*n,0);


(*n)++;// увеличиваем количество столбцов в матрице
	
}


void program(simplex aa)
{
int i,j;	

for(i=0;i<aa.m;i++)//выполняем проверку на отрицательность свободных членов
if(aa.mas[i][aa.n]<0) rightnotminus(aa.mas[i],aa.n+1,&aa.ogranich[i]);

for(i=0;i<aa.m;i++,printf("%i\n",aa.ogranich[i-1]))
for(j=0;j<=aa.n;j++) printf("%f\t",aa.mas[i][j]);
	
	
printf("\n");	
	
for(i=0;i<aa.m;i++)	// в случае <= добавляем вектор с 1 и нулями
//в случае >= добавляем вектор с 1 и нулями
if(aa.ogranich[i]==1)	add_element(aa.mas,aa.m,&aa.n,i+1);
else if(aa.ogranich[i]==2)	add_element(aa.mas,aa.m,&aa.n,-(i+1));
	
	
printf("\n\n");
for(i=0;i<aa.m;i++,printf("%i\n",aa.ogranich[i-1]))
for(j=0;j<=aa.n;j++) printf("%f\t",aa.mas[i][j]);
	
}




int main()
{
int i,j;	
/*
Пример
F = -2x1 + 5x2 -3x3 -> min 
-6x1 + 4x2 - 2x3 <=2
 4x1 + 3x2 + 9x3 <=1
  x1 + 3x2 - 5x3 <=4  
*/	
simplex sm;	
sm.m=3;
sm.n=3;

sm.celfun = (double *)malloc((sm.n + 1) * sizeof(double));
sm.celfun[0]=-2;
sm.celfun[1]=5;
sm.celfun[2]=-3;
sm.celfun[3]=0;
sm.strem=0;//min

for(i=0;i<=sm.n;i++)
printf("%f\t",sm.celfun[i]);
printf("\n\n");

sm.mas = (double**)malloc(sm.m * sizeof(double*));
for(i=0;i<sm.m;i++)
sm.mas[i]=(double *)malloc((sm.n + 1) * sizeof(double));

sm.mas[0][0]=+6;
sm.mas[0][1]=-4;
sm.mas[0][2]=+2;
sm.mas[0][3]=-2;

sm.mas[1][0]=4;
sm.mas[1][1]=3;
sm.mas[1][2]=9;
sm.mas[1][3]=1;

sm.mas[2][0]=-1;
sm.mas[2][1]=-3;
sm.mas[2][2]=+5;
sm.mas[2][3]=-4;


sm.ogranich=(unsigned char *)malloc(sm.m * sizeof(unsigned char));
sm.ogranich[0]=2;//<=
sm.ogranich[1]=1;//<=
sm.ogranich[2]=2;//<=


for(i=0;i<sm.m;i++,printf("%i\n",sm.ogranich[i-1]))
for(j=0;j<=sm.n;j++) printf("%f\t",sm.mas[i][j]);
printf("\n");

program(sm);

	return 0;
	}

Последний раз редактировалось ivan.tiran; 04.12.2014 в 21:44.
ivan.tiran вне форума Ответить с цитированием
Старый 04.12.2014, 23:01   #6
ivan.tiran
Форумчанин
 
Аватар для ivan.tiran
 
Регистрация: 24.08.2011
Сообщений: 138
По умолчанию

всем благодарен за помощь
ivan.tiran вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
ошибка при вызове процедуры Emperator12 Общие вопросы Delphi 8 22.09.2012 00:52
Ошибка при вызове openFileDialog ---FISHER--- C# (си шарп) 7 02.03.2011 13:25
beginthread, ошибка при вызове Dreanks Помощь студентам 2 28.10.2010 14:09
Ошибка компиляции при вызове подпрограммы Android_ua Общие вопросы C/C++ 4 02.03.2010 12:20