LINUX.ORG.RU

двумерный массив в heap на c


0

2

Здравствуйте, изучаю форматы файлов изображений, решил попробовать написать конвертер для чего-то вроде raw: http://pastebin.com/LgPxFTb8
Эта программа должна создать файл, указатель на массив int'ов в памяти, забить массив рандомными данными (0 и 1) и записать их в файл.
Указатель объявлен так:
int **img_array;

Вот выделение памяти:
img_array = (int**) malloc ( LENGTH * HEIGHT * sizeof(int) );

Потом я уже использую его как двумерный массив:
img_array[rows][cols] = rand()%2;

На этом месте программа выдает сегфолт. Скорее всего, ошибка очевидная, но с heap'ом раньше я работал только на c++, там можно было просто int x = new y
Прошу помощи, заранее спасибо

давай весь код, rows и cols не инициализированы, например; ну и нафига здесь двумерный массив, если всё равно пишешь рандомные данные

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

двумерный массив нужен для того, чтобы потом нормальное изображение писать и сохранить читаемость
а если у меня 1600x1200 будет?

Весь код по ссылке, uint rows, cols вы, наверное, пропустили

ms-dos32
() автор топика

программа должна создать файл, указатель на массив int'ов в памяти

int **img_array вернёт указатель на массив указателей, а не на массив int'ов.

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

Верно, сделал симуляцию двумерного массива через одномерный и все пошло. Спасибо всем за ответы

ms-dos32
() автор топика

Если тебе не критично, попробуй пользоваться всё-таки одномерным:

int * img_array;
img_array = malloc(W * H * sizeof(int));
img[x + y * W] = rand() % 2;

schizoid ★★★
()

С двухмерными массивами работают так:

SomeType* foo = new SomeType[width*height];
SomeType bar = foo[x + y*width]; 

Или так:

SomeType bar = foo[x*height + y];  // Fortran style
dmfd
()

я работал только на c++, там можно было просто int x = new y

Есть ощущение, что и с c++ ты также работал.

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

кстати говоря, кастить malloc — это очень-очень bad habbit, не надо так делать

Давно? А то обычно я только с кастом malloc и видел.

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

очень давно, смотри выше по треду ссылку на faq.

в том то и беда, что это bad habbit: в староглинянные времена (до ANSI C), когда писались первые туториалы, это было ещё нужно, с тех пор все эту ошибку как попугаи повторяют.

смотри так же например http://bytes.com/topic/c/answers/215856-why-casting-malloc-bad-thing

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

Вот, плюсую, самый правильный вариант (всё думал, неужели никто не напишет... хотел уже сам писать).

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

фортран стайл мне не нравится

В MKL так, емнип.

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

Никогда так не делайте, массив массивов - известный антипаттерн.

если без необходимости, задачи где так надо делать имеют место быть.

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

cuda не щупал, не знаю, но из того, что гугля на первой стренице выдаёт, это совсем другая песня.

malloc возвращает void * — тут приведение типов лишнее

cudaMalloc же ожидает void ** как аргумент — тут без каста ни как

http://c-faq.com/~scs/cclass/int/sx8.html

One side point about pointers to pointers and memory allocation: although the void * type, as returned by malloc, is a ``generic pointer," suitable for assigning to or from pointers of any type, the hypothetical type void ** is not a ``generic pointer to pointer."

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

Обработка списков переменной длины, которая может меняться. Да в общем-то и в классе вычислительных задач были примеры, правда сходу вспомнить не удаётся.

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

Нет, конечно, у меня в ололо-высокопроизводительном коде встречаются штуки вроде std::vector<thrust::device_vector<Something> >, но только потому, что внешний массив маленький и дёргается сравнительно редко.

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

списков переменной длины

Да, уже сам догадался. См. пост выше.

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

А вот K&R не ANSI C, а гораздо древнее. Ещё один попугай.

Я здесь вижу только одного попугая, не осилившего даже предисловие книги.

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

В «туториалах» для новичков и говноучебниках - сплошь и рядом.

В тех же, где на С предлагают делать приведение типов для malloc?

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

До ANSI C, говорят, касты были нужны, а сейчас их используют в C++ и иногда в C

ms-dos32
() автор топика
Ответ на: комментарий от Dragon59

ещё раз, изначально malloc в K&R был char *malloc(int) и каст был необходим. начиная с ANSI C его декларация становится void *malloc(size_t) и тут каст излишен, но примеры в K&R никто переделывать не стал.

хоть формально ты и прав — да, в K&R это явно оговаривается, но тут праотцы явно не совсем правы. почему этот абзатц остался в книге я не знаю.

http://c-faq.com/malloc/mallocnocast.html

явное приведение типов скрывает ряд ошибок и не приносит никаких преимуществ. поэтому и не нужен.

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

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

schizoid ★★★
()
Ответ на: комментарий от ms-dos32

а что означает последняя строка

Присваивание же. Навигация по массиву к нужной ячейке, так сказать, эмуляция двухмерности.

schizoid ★★★
()
Ответ на: комментарий от ms-dos32

А есть встраиваемые системы, например. Или ещё какие ограничения. Или изображение на гигобайты. В общем, иметь в виду особенности работы менеджеров памяти не помешает.

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

Можно память использовать по минимуму (по несколько килобайт писать в файл за раз)

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