[РЕШЕНО] Ошибка сегментирования при вызове malloc()

Толком не сплю уже неделю - отлаживаю один алгоритм. И вот только он подал признаки жизни и пришла пора тестировать на серьезных вещах - вот вам пожалуйста - сабж

Имеется участок кода

        nv = 17
        n = 6*nv - 4;
	nb = 3*nv - 2;
	nr = nb - 1;
	n_ef = 2*nv - 2;

	// Set mass
	m = new double[nb];

	memset(m, 0, nb*sizeof(double));

	for (int i = 0; i < nv; i++)
	{
		int k = 3*i;

		m[k] = mv;
		m[k+1] = mt;
		m[k+2] = mt;
	}

	// Create matrixes

	A = create_matrix(nb, nb+nr);

	L = create_matrix(nr, nb);
	L1 = create_matrix(nr, nb);

	for (int i = 0; i < nr; i++)
	{
		L[i][i] = 1;
		L[i][i+1] = -1;
	}

	K = create_matrix(nb, nr);
	K1 = create_matrix(nb, nr);

	for (int i = 0; i < nv-1; i++)
	{
		int j = 3*i;

		K1[j][j] = K[j][j] = -1;
		K1[j+1][j] = K[j+1][j] = 1;

		K1[j+1][j+1] = K[j+1][j+1] = 1;
		K1[j+2][j+1] = K[j+2][j+1] = -1;

		K1[j+2][j+2] = K[j+2][j+2] = -1;
		K1[j+3][j+2] = K[j+3][j+2] = 1;
	}
	lock = new bool[nr];

	for (int i = 0; i < nr; i++)
		lock[i] = true;

	p = new double[nb];
	q = new double[nb];

	memset(p, 0, nb*sizeof(double));
	memset(q, 0, nb*sizeof(double));

	Tef = new double[n_ef];
	ef_sign = new int[n_ef];

	n_ef = 32;
	coup = new coup_t[n_ef];
	for (int i = 0; i < n_ef; i++)
	{
		coup_t tmp = new CEFcoupling();
		coup[i] = tmp;
	}

Ошибка возникает при nv = 18 в строке

coup_t tmp = new CEFcoupling();

При nv = 17 все работает. Анализ крэша в отладчике дает стек вызовов из которого понятно, что падает все на вызове malloc().

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff707668f in _int_malloc () from /usr/lib/libc.so.6
(gdb) bt full
#0  0x00007ffff707668f in _int_malloc () from /usr/lib/libc.so.6
No symbol table info available.
#1  0x00007ffff7078030 in malloc () from /usr/lib/libc.so.6
No symbol table info available.
#2  0x00007ffff7919e9d in operator new(unsigned long) () from /usr/lib/libstdc++.so.6
No symbol table info available.
#3  0x00007ffff7919f99 in operator new[](unsigned long) () from /usr/lib/libstdc++.so.6
No symbol table info available.
#4  0x0000000000401fe9 in ode_systems_init () at train.cpp:177
No locals.
#5  0x0000000000400b69 in main () at main.cpp:23
        solver = 0x400a50 <_start>

Если инструкцию, вызывающую сбой убрать, при nv=18 сбой возникает на любой другом, следующим за ним операторе new.

Короче говоря я в шоке

P. S.:
Забыл приложить код вызываемых функций

//-------------------------------------------------------------------
//
//-------------------------------------------------------------------
matrix_t create_matrix(int n, int m)
{
	matrix_t tmp = 0;

	tmp = new matrix_str_t[n];

	for (int i = 0; i < n; i++)
	{
		tmp[i] = new double[m];
		memset(tmp[i], 0, m*sizeof(double));
	}

	return tmp;
}

и описание используемых типов

typedef double* matrix_str_t;
typedef matrix_str_t* matrix_t;

Точно выяснено - ошибка зависит от того, сколько динамической памяти выделено перед роковым вызовом. Неужели при имеется ограничение на размер кучи???
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb
http://rusrailsim.org
Вы можете сказать, что я не по теме, и будете отчасти правы.
Но stl векторы как раз и предназначены для того, чтобы не копаться в таком коде.
Дополнительного огонька подливают дополнительные выделения памяти для многомерных матриц. Я давно пришёл к конструкциям вида a[y*xsize+x].
Впрочем, это, оффтоп. Код не читал, ибо подобного рода нагромождения не вдохновляют...

PS Разве что бросилась в глаза эта конструкция:
for (int i = 0; i < nr; i++)
	{
		L[i][i] = 1;
		L[i][i+1] = -1;
	}

Сочетание "i<nr" и "[i+1] =" обычно не сулит ничего хорошего ;)
такие дела.
Вроде как далеко ходить не надо. Уже в самом начале кода
maisvendoo
Имеется участок кода

nv = 17
n = 6*nv - 4;
nb = 3*nv - 2;
nr = nb - 1;
n_ef = 2*nv - 2;

// Set mass
m = new double[nb];

memset(m, 0, nb*sizeof(double));

for (int i = 0; i < nv; i++)
{
int k = 3*i;

m[k] = mv;
m[k+1] = mt;
m[k+2] = mt;
}

nb = 3*nv - 2; и размер m[] соответствующий, а в цикле идет обращение к m[k+2], где в максимуме достигает к=3*(nv-1)+2,
что заведомо выходит за границы выделенной для массива памяти, потому что
3*(nv-1)+2 = 3*nv-3+2 = 3*nv-1
3*nv-2 < 3*nv-1
Ну а дальше вы огребаете последствия обращения за границы выделенной памяти.
kurych, спасибо что не поленились посмотреть. Я замыленным взглядом пропустил бы - неделю в разнообразных отладках а сроки жмут.

Исправил это на

        m[0] = mv;
	m[1] = mt;

	for (int i = 2; i < nb-2; i += 3)
	{
		m[i] = mt;
		m[i+1] = mv;
		m[i+2] = mt;
	}

	m[nb-2] = mt;
	m[nb-1] = mv;

и заработало не только это, а правильно стали вычислятся все силы.

Огромное человеческое спасибо :)

P.S.: Динамическая память такая динамическая :)

P.P.S.: Хотя с силами я поторопился, но это уже другой специфичный вопрос...
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb
http://rusrailsim.org
Получил вот такой график

По заявлению руководителя это "то что надо", да я и сам это понимаю.

Хочу поблагодарить откликнувшихся на сабж людей, без вас нашел бы ошибку но не сегодня. А ложка, как известно, дорога к обеду. Хорошо, что у нас такое сообщество :)
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb
http://rusrailsim.org
оси не подписаны!
такие дела.
cucullus
оси не подписаны!
Рабочий вариант. Не оформил ещё.

А так у меня есть самописная библиотека которая генерирует в латэхе красивый отчет. Не прикрутил ещё к этому проекту, не успел
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb
http://rusrailsim.org
Ну, вот с подписанными осями после доводки )
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb
http://rusrailsim.org
крысота! легенда, правда, напрашивается в правый верхний угол.

А что есть отрицательная тяга? Это же не пневмоторможение? Включение заднего хода?
В случае штатного торможения такой колбасни быть не должно вроде. (В сферическом поезде с одинаковыми по весу вагонами).
Если поезд натянут "в струнку" (а он только что был под тягой, значит так и должно быть) при идеальном торможении вообще не должно быть биений по идее.
такие дела.
cucullus
А что есть отрицательная тяга?
Рекуперация или реостатное торможение. Двигатели переводятся в генераторный режим и отдают энергию либо в сеть, либо на тормозные резисторы.

Конечно, так никто не рекуперирует особенно на грузовых. Но этот результат - тест модели.
Да пребудет с нами Сила...!
CPU Intel Core i9 10900-KF/RAM DDR4 128 Gb/NVidia GForce GTX 1080 Ti Turbo 11Gb/SSD M2 512 Gb/HDD Seagate SATA3 2 Tb/HDD Toshiba 3Tb/HDD Toshiba 6Tb
http://rusrailsim.org
 
Зарегистрироваться или войдите чтобы оставить сообщение.