Возврат массива функцией

Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain

Аватара пользователя
FLOODkOFF
Сообщения: 4
Зарегистрирован: 30 авг 2007, 21:32
Откуда: Санкт-Петербург
Контактная информация:

BBB писал(а):

Код: Выделить всё

mas[i] = (char *) malloc ( (*y) * [B]sizeof (char *)[/B]); //<- [B]вот так верно[/B]
да да, точно, но тогда уж и эта строчка вот так:
BBB писал(а):

Код: Выделить всё

mas[i] = (char *) malloc ( (*y) * [B]sizeof (char)[/B]);
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

BBB писал(а):Можно, кстати, вообще выделить одним куском памяти. Правда, в этом случае формально массив будет одномерный, и для обращения к элементам мссива придется "на лету" далать "преобразование" из двух "логических" координат в одну "физическую". Но зато здесь можно будет воспользоваться оператором new:

Код: Выделить всё

int* fun(int* xSize, int *ySize) //xSize, ySize -размерности
{ 
int* mas;
*xSize=10; *ySize=14//вычислили необходимые размеры

mas = new int [(*xSize) * (*ySize)]
return mas;
};
// Обращение к элементу (i, j) в этом случае будет:

mas [(i * xSize) + j]
Зачем так сложно? Можно сделать два массива - один одномерный большой, и второй одномерный маленький содержащий срез из указателей на элементы большого
Для строк писать сейчас влом, вот фрагмент программы которая работает с изображениями. Работа с пискселями: RawImage->scans[j]

.h файл

Код: Выделить всё

/*......*/
typedef struct RawImageT {
	rimg_ui4 width;
	rimg_ui4 height;
	rimg_ui2 bpp;
	rimg_byte** scans;
	rimg_byte* raw_data;
} RawImage;

rimg_error_t alloc_raw_image(int width, int height, int bpp, RawImage** out_val);
/*......*/
.c файл

Код: Выделить всё

rimg_error_t alloc_raw_image(int width, int height, int bpp, RawImage** out_val) {
	RawImage* outval0 = malloc(sizeof(*outval0));
	if (outval0) {
		rimg_byte* raw_data = 0;
		int scanlength = (width * bpp) / CHAR_BIT;
		memset(outval0, 0, sizeof(*outval0));
		if (0 != (scanlength & 3)) {
			scanlength = (scanlength | 3) + 1;
		}
		raw_data = malloc(scanlength * height);
		if (raw_data) {
			rimg_byte **scans = malloc(height * sizeof(*scans));
			if (scans) {
				int i;
				for (i = 0; i != height; ++i) {
					scans[i] = raw_data + (scanlength * i);
				}
				outval0->width = width;
				outval0->height = height;
				outval0->bpp = bpp;
				outval0->raw_data = raw_data;
				outval0->scans = scans;
				*out_val = outval0;
				return RIMG_OK;
			} else {
				free(raw_data);
				free(outval0);
				return RIMG_MEM_ERROR;
			}
		} else {
			free(outval0);
			return RIMG_MEM_ERROR;
		}
	} else {
		return RIMG_MEM_ERROR;
	}
}
2B OR NOT(2B) = FF
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

FLOODkOFF писал(а):да да, точно, но тогда уж и эта строчка вот так:

Код: Выделить всё

mas[i] = (char *) malloc ( (*y) * sizeof ([b]char[/b]));
Не совсем. Я, конечно, тоже описался (операция copy-paste... едрит ее :) )
Так как в итоге массив содержит int-ы, а не char-ы, то:

Код: Выделить всё

mas[i] = (char *) malloc ( (*y) * sizeof ([b]int[/b]));
BBB
Сообщения: 1298
Зарегистрирован: 27 дек 2005, 13:37

Absurd писал(а):Зачем так сложно? Можно сделать два массива - один одномерный большой, и второй одномерный маленький содержащий срез из указателей на элементы большого
Положим, это весьма спорное утверждение. В этих двух массивах вполне можно запутаться (как с обращением, так и с выделением/освобождением памяти).
Absurd
Сообщения: 1228
Зарегистрирован: 26 фев 2004, 13:24
Откуда: Pietari, Venäjä
Контактная информация:

Обращение, как и было уже описано, делается с помощью raw_image->scans[j]
Выделение - с помощью alloc_raw_image(...) которую я привел.

Освобождение делается при помощи которая лежит в том же *.c файле

Код: Выделить всё

void free_raw_image(RawImage* img) {
	free(img->scans);
	free(img->raw_data);
	free(img);
}
2B OR NOT(2B) = FF
Ответить