LINUX.ORG.RU

Динамический массив


0

0

Господа, что то я не могу понять фишку с этими указателями.
Изучаю C/C++.

Передавая в функцию какой-либо параметр там по-любому используется его копия?
Например: необходимо в одной ф-и инициализировать двумерный массив, а в другой его обработать (модифицировать).

//------------------------------------------------------------------------------

void func1(double *m1){
	m1 = new double [5];
}
//------------------------------------------------------------------------------

void func2(double **m2){
	m2 = new double * [5];
	for (int i = 0; i < 5; ++i)
		m2[i] = new double [5];
}
//------------------------------------------------------------------------------

int main(){
	double *m1, **m2;
	
	func1(m1);
	func2(m2);
}
//------------------------------------------------------------------------------


После выполнения func1 и func2 в ф-и main мы имеем m1 и m2 указывающие на соответствующие массивы?
А то при работе с сабжем постоянно segmentation falut получаю.

> Передавая в функцию какой-либо параметр там по-любому используется его копия?
Нет, все типы кроме массивов передаются _по значению_. Для того, чтобы передать по ссылке нужно явно указать это в прототипе:
void func1(double& *m1);

phoenix ★★★★
()

Я тоже сегодня сабж изучал :) Совпадение. Уже третий за день в Development с массивами...

>Передавая в функцию какой-либо параметр там по-любому используется его копия?

Можно передать по ссылке (by reference) используя амперсанд & перед переменной в аргументах функции.

Selecter ★★★★
()

AFAIK переменные созданные в свободной памяти (через new) доступны только внутри функции.

Сильно не бейте, если не прав.

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

m1 address (from func1): 0x804a008
m2 address (from func2): 0x804a038
m1 address (from main): 0x80489a0

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

> AFAIK переменные созданные в свободной памяти (через new)
> доступны только внутри функции.

не прав ....

наоборот, это автоматические переменные не существуют _после_
завершения функции. то, что получено с помощью malloc()/new()
прекрасно себя чувствует до free()/delete().

> Сильно не бейте, если не прав.

(серия отвлекающих джебов, прорыв в ближнюю дистанцию ... ;)

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

Почему тогда m1[0] не получает значение?

#include <iostream>

void func1(double *m1){
	m1 = new double [5];
	m1[0] = 0.5;
	std::cout << "m1 address (from func1): " << m1 << std::endl;
}
//------------------------------------------------------------------------------


void func2(double **m2){
	m2 = new double * [5];
	for (int i = 0; i < 5; ++i)
		m2[i] = new double [5];
	std::cout << "m2 address (from func2): " << m2 << std::endl;
}
//------------------------------------------------------------------------------


int main(){
	double *m1, **m2;
	
	func1(m1);
	func2(m2);
	std::cout << m1[0] << std::endl;
	std::cout << "m1 address (from main): " << m1 << std::endl;
}
//-----------------------------------------------------------------------------


m1 address (from func1): 0x804a008
m2 address (from func2): 0x804a038
3.23905e-171
m1 address (from main): 0x8048a00

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

2Selecter:

> Почему тогда m1[0] не получает значение?

Ну ты же сам своей программой на свой вопрос и отвечаешь!

> m1 address (from func1): 0x804a008

> m1 address (from main): 0x8048a00

Видно, что у тебя _два_ массива m1.

Тебе так надо:

void func1(double **m1){
        *m1 = new double [5];
        (*m1)[0] = 0.5;
        std::cout << "m1 address (from func1): " << *m1 << std::endl;
}

В main():

func1(&m1);

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

Понятно. Значит процессор из книги не выучил уроки.

Selecter ★★★★
()
Ответ на: комментарий от Die-Hard

2Selecter:

Кстати, то был "фортранный" подход. На Це/ЦеПП обычно нечто 
вроде такого принято:

double *func1(int thesize){
  double *m = new double [thesize];

  m[0] = 0.5;
  std::cout << "m address (from func1): " << m << std::endl;
  return m;
}

В main():

double *m1=func1(5);

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

А если

>Изучаю C/C++.

т.е. С++, то проще использовать smart pointer, что то типа

SmartPointer<double> *func1(int thesize){

SmartPointer<double> m = SmartPointer<double>(new double [thesize]);

return m;

}

В этом случае избавляешься от проблеммы очистки памяти.

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