LINUX.ORG.RU

Динамическое выделение памяти под массив


0

0

Переношу одну программулину с C под *nix на C++ под M$. Делаю выдение 
массива через new[]:


//Allocate memory for arrays

	Ax = new  double *[N];
	if(Ax == NULL)
		err_exit(1);
	else
		for(int i=0;i<N;i++){
			Ax[i] = new double[N-1];
			if(Ax[i] == NULL)
				err_exit(1);
		}


	Ax[5][3] = 5.0;

	//free arrays memory

	for(int i=0;i<N;i++){
		delete Ax[i];
	}
	delete [] Ax;

Программа вылетает с ошибкой - что я делаю не так?


Да, естественно, Ax обЪявлен, как

double **Ax;

dsoc
() автор топика

delete[] Ax[i];

хотя это здесь не существенно.

k_andy ★★★
()
Ответ на: комментарий от krum

> Не так? "с C под *nix на C++ под M$"

Ах-ха. Я б уж если и переделывал, то делал бы кроссплатформенным.

k_andy ★★★
()
Ответ на: комментарий от krum

Для интереса, налабал такой вот код

int main(int argc, char** argv)
{

	//Allocate memory for arrays
	int i,j;

	

	Ax = (double **)malloc(N * sizeof(double *));
	if(!Ax) 
		err_exit(1);
	else{
		for(i=0;i<N;i++){
			Ax[i] = (double *)malloc((N-1) * sizeof(double));
			if(!Ax[i]){
				cleanup(Ax,N);
				err_exit(1);
			}
		}
	}

	Ax[3][1] = 5.0;
	//free arrays memory
	cleanup(Ax,N);

	
	return 0;
}

void cleanup(double **A, int x)
{
	int i;
	for(i=0;i<x;i++)
		free(A[i]);
	free(A);
}

Тоже - консольное выражение при занесении значения в Ax[i][j] - нафиг вылетает :( Может кто привести Пример КАК надо выделить память для динамического массива N*M? А то уже голова пухнет.

dsoc
() автор топика
Ответ на: комментарий от krum

Да, ошибка такая

Unhandled exception at 0x0041149f in parvich.exe: 0xC0000005: Access violation writing location 0xfdfdfe05.

dsoc
() автор топика

Я может чего-то не понимаю, но почему у тебя память под матрицу выделяется в разых местах (имеются ввиду разные куски памяти), а обращаешься ты к элементам матрицы как будто матрица лежит в одном выделенном(непрерывном, замечу) сегменте памяти?

jr_A
()
Ответ на: комментарий от jr_A

Как я понимаю методику выделкния памяти:

1)Объвляем указатель на указатель double **Ax

2)Выделяем массив из N-ного количества указателей типа double на double

3)Для каждого указателя выделяем строку матрицы из M элементов.

Эти действия производятся последовательно, почему в разных местах?

dsoc
() автор топика
Ответ на: комментарий от k_andy

k_andy

/****************************************************
parvich.h
Defines global structures and functions declarations
*****************************************************/

#define N 3			//number of nodes
#define M 5			//number of brunches

dsoc
() автор топика
Ответ на: комментарий от dsoc

Попробуй представить карту памяти при таком выделении. Вся память у тебя будет сотоять из N отрезков длинной N*sizeof (double). Они не будут идти последовательно друг за другом в общем случае! Обращение вида: A[i][j] - это обращение к памяти которая сидит по адресу: A + i*N+j. В случае выделения памяти по твоему алгоритму - залет на SIGSEGV гарантирован.

jr_A
()
Ответ на: комментарий от dsoc

Не единственный, но выход. Так работать будет. Кстати я слегка намудрил выше (комментировал не тот код, который надо было бы), но ты внимательно смотри на то, что делаешь и следи за памятью - тогда все будет просто зашибись.

jr_A
()
Ответ на: комментарий от dsoc

> Как я понимаю методику выделкния памяти:

Так выделяют память первокурсники, еще не освоившие Си.

> #define N 3 //number of nodes

Тебе не кажется, что в таком случае A[3] из "налабанного кода" выходит за пределы массива из 3-х элементов?

tailgunner ★★★★★
()
Ответ на: комментарий от jr_A

Мда, позор на мою(неседую голову) :) Просто до этого N и M были по полтиннику :(((

p.s. Остановлися на последнем варианте с malloc, всем thx

dsoc
() автор топика
Ответ на: комментарий от dsoc

> Остановлися на последнем варианте с malloc

Это зря. Уж лучше тогда std::vector<std::vector<double> >. Не пишите C-код на C++.

k_andy ★★★
()


1. exception unsafe by design
2. местами попросту некорректно (проверка на NULL)

вывод: продолжаем читать Страуструпа и gotw.ca

// wbr

klalafuda ★☆☆
()

>то я делаю не так?

сам же отвечаешь на свой вопрос:

>Переношу одну программулину с C под *nix на C++

может не стоит на С++ её переносить, если ты сам толком его не знаешь?

Reset ★★★★★
()
Ответ на: комментарий от Reset

Reset

Может быть, но не от меня это зависит. :(

dsoc
() автор топика
Ответ на: комментарий от jr_A

>Обращение вида: A[i][j] - это обращение к памяти которая сидит по адресу: A + i*N+j. В случае выделения памяти по твоему алгоритму - залет на SIGSEGV гарантирован.

только если у тебя статический массив вида double A[100][100] //N=100

Reset ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.