powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / C++ [игнор отключен] [закрыт для гостей] / Си. Освободить память 2-мерного сторкового массива
25 сообщений из 308, страница 3 из 13
Си. Освободить память 2-мерного сторкового массива
    #40129803
White Owl
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Пока нарисовал строки.

"A" - это 1 символ.

"А1" - это два символа, объединенных в одномерный массив

{"А1", "А2", "А3"} - это уже двумерный массив.

{"А1", "А2", "А3"}
{"B1", "B2", "B3"} - это трехмерный массив
{"C1", "C2", "C3"}


Сейчас с указателями попробую.
Рисунок не правильный. В памяти нету объема. Вся память компьютера это один большой листочек в клеточку. Плоский. Так что первые картинки - правильно, а последняя (трехмерный массив) это уже неправильно.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129804
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Так должно быть?
Код: plaintext
1.
stroka[x] = (char**)malloc(M*sizeof(char*));


Да
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129805
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Dima T

Тебе в тестеры надо, ты умудрился откомпилировать то что не должно компилироваться. Не пользуйся тем компилятором.


Вот такой компилятор:
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

Странно, GCC очень дотошный, более мелкие ляпы отказывается компилировать. Надо попробовать.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129807
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
mayton
Уткъ, дружище. Судя по профилю ты - Postgres-щик.

Тебе действительно очень надо кодить на сях? Я почему спрашиваю. Для админ- или девопс- задачек
можно задействовать целый спектр языков которые и проще и быстрее в освоении. Ruby, Python, e.t.c.


Нужно сделать высоконагруженное приложение с парралельными запросами и копированием данных туда-сюда на огромное количество серверов (1000+)

Поэтому выбор пал на Си (+libpq), как родной язык для PostgreSQL.

В принципе, это все работало на psql+bash, но логика стала на столько сложна, что это пора выносить на уровень приложения.

У Си оказались свои особенности, с которыми потихоньку разбираюсь.

Хорошо этот раздел форума оказался живой и тут есть реальная помощь :-)

Ну и сами понимаете, Си - это что-то реальное, основательное.

Вот, к примеру, было непонятно кое-что с копированием данных - открыл исходник PostgreSQL и взял код прям оттуда, немного адаптировав под себя.

Си это инструмент для написания драйверов и т.п. Я думал это студенческое творчество, типа задали сделать на чистом С, для этого потянет, а для реального ПО - нет.

Во-первых элементарно можно накосячить, например пропустил ты тут звездочку 22426622 , и вроде работает, а на самом деле ты такие себе грабли подложил что устанешь их искать когда наступишь. Ты выделил M байт (char 1 байт) вместо M*8 байт (char* 8 байт), таким образом ты будешь работать с памятью за пределами массива, и оно будет работать до какого-то момента. В лучшем случае словишь Segmentation fault, в худшем будешь удивляться почему меняются данные в совсем другой переменной.

Во-вторых то что мы с тобой сочинили тянет только на студенческую поделку, 100500 вызовов malloc() это тормоз и неэффективное использование памяти. Это надо оптимизировать, например как тут показывал 22426324

Возьми хотя бы С++, в нем есть все возможности С и более удобные средства управления памятью. По производительности они не отличаются. Хотя и это не лучший выбор, т.к. завтра ты захочешь распараллелить работу, а тут это нетривиально.
В идеале надо брать Java, Go, C# или что-то подобное, где скрыты все рутинные моменты и можно писать не сильно опасаясь выстрелов в ногу.

Тут тестировали скорость работы разных ЯП 21542058 только не зацикливайся на тех цифрах, там нагрузку на проц мерили, а у тебя на память и ввод/вывод, поэтому все ЯП будут одинаковы.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129809
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Нужно сделать высоконагруженное приложение с парралельными запросами и копированием данных туда-сюда на огромное количество серверов (1000+)
Ну так возьмите Java. Рантайм есть везде, драйвера к базам данных - тоже, но вы, при этом, не будете наступать на кучу разнообразных и совершенно неочевидных грабель.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129822
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Уткъ
Так должно быть?
Код: plaintext
1.
stroka[x] = (char**)malloc(M*sizeof(char*));


Да


Отлично :-)
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129823
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Уткъ
пропущено...


Вот такой компилятор:
gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-44)

Странно, GCC очень дотошный, более мелкие ляпы отказывается компилировать. Надо попробовать.


Я по умолчанию запускаю gcc file.c -o file

наверняка там какая-то опции запуска есть, которые повышают блидетьность.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129826
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Уткъ
пропущено...


Нужно сделать высоконагруженное приложение с парралельными запросами и копированием данных туда-сюда на огромное количество серверов (1000+)

Поэтому выбор пал на Си (+libpq), как родной язык для PostgreSQL.

В принципе, это все работало на psql+bash, но логика стала на столько сложна, что это пора выносить на уровень приложения.

У Си оказались свои особенности, с которыми потихоньку разбираюсь.

Хорошо этот раздел форума оказался живой и тут есть реальная помощь :-)

Ну и сами понимаете, Си - это что-то реальное, основательное.

Вот, к примеру, было непонятно кое-что с копированием данных - открыл исходник PostgreSQL и взял код прям оттуда, немного адаптировав под себя.

Си это инструмент для написания драйверов и т.п. Я думал это студенческое творчество, типа задали сделать на чистом С, для этого потянет, а для реального ПО - нет.

Во-первых элементарно можно накосячить, например пропустил ты тут звездочку 22426622 , и вроде работает, а на самом деле ты такие себе грабли подложил что устанешь их искать когда наступишь. Ты выделил M байт (char 1 байт) вместо M*8 байт (char* 8 байт), таким образом ты будешь работать с памятью за пределами массива, и оно будет работать до какого-то момента. В лучшем случае словишь Segmentation fault, в худшем будешь удивляться почему меняются данные в совсем другой переменной.

Во-вторых то что мы с тобой сочинили тянет только на студенческую поделку, 100500 вызовов malloc() это тормоз и неэффективное использование памяти. Это надо оптимизировать, например как тут показывал 22426324

Возьми хотя бы С++, в нем есть все возможности С и более удобные средства управления памятью. По производительности они не отличаются. Хотя и это не лучший выбор, т.к. завтра ты захочешь распараллелить работу, а тут это нетривиально.
В идеале надо брать Java, Go, C# или что-то подобное, где скрыты все рутинные моменты и можно писать не сильно опасаясь выстрелов в ногу.

Тут тестировали скорость работы разных ЯП 21542058 только не зацикливайся на тех цифрах, там нагрузку на проц мерили, а у тебя на память и ввод/вывод, поэтому все ЯП будут одинаковы.


Да там по сути простые операции, просто надо массив серверов и по ним подключения идут потом.
С++ да, рассматриваю.
Остальные вряд ли, т.к. требуется парралельное выполнение запросов, т.е. использование библиотеки libpq
+ надо чтоб компилился и под винду и под linux
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129827
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Basil A. Sidorov
Уткъ
Нужно сделать высоконагруженное приложение с парралельными запросами и копированием данных туда-сюда на огромное количество серверов (1000+)
Ну так возьмите Java. Рантайм есть везде, драйвера к базам данных - тоже, но вы, при этом, не будете наступать на кучу разнообразных и совершенно неочевидных грабель.


А что такое runtime?
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129829
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Кстати, правильлно ли я понял что количество столбцов массива надо обязательно через константу присваивать, а количество строк можно из константы вывести в переменную?

Т.е. K вывести в переменную:

Код: plaintext
1.
2.
3.
#define K 2 //количество строк
#define M 3 //количество столбцов
#define N 100 // максимальная длинна строки
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129833
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
А что такое runtime?
J(ava)R(untime)E(nvironment).
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129835
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А что такое runtime?компоненты, библиотеки времени выполнения. Без Runtime код работать не будет
Условно
Для Java - это JRE
Для C# - .NET
и т.д.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129837
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Ustinov
А что такое runtime?
компоненты, библиотеки времени выполнения. Без Runtime код работать не будет
Условно
Для Java - это JRE
Для C# - .NET
и т.д.

Звучит довольно мерзко.


А разве для выполнения скомпилированного exe файла на С# требуются какие-то запущенные процессы в ОС?
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129838
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добавил проверку выделилась ли память при аллокации, надеюсь верно написал:



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
	char*** stroka = (char***)malloc(K*sizeof(char**));
    if (NULL == stroka) {printf("Memory does not given.\n");return 1;}
for(x=0;x<K;x++)
{
	//выделение памяти для 2-мерного массива
    stroka[x] = (char**)malloc(M*sizeof(char*));
	if (NULL == stroka[x]) {printf("Memory does not given.\n");return 1;}
    for(i=0;i<M;i++)
    {
		//выделение памяти для 1-мерного массива
        stroka[x][i] = (char*)malloc(N*sizeof(char));
		if (NULL == stroka[x][i]) {printf("Memory does not given.\n");return 1;}
    }


}
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129840
Фотография mayton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ

Нужно сделать высоконагруженное приложение с парралельными запросами и копированием данных туда-сюда на огромное количество серверов (1000+)

В современном бизнес-программировании большая пропускная способность вобщем-то не зависит
от выбора языка разработки. А зависит от того насколько грамотно ты смог распараллелить
задачу на независимые части. Например разработчик AWS-Lambda делает бизнес-функцию затем
закидывает ее в облако и далее ее можно умножить на 1000 просто в конфиге. Много экземпляров
функции + грамотно партицированный S3 storage решают почти все мыслимые задачи.

Я не знаю что ты там надумал в плане с копированием 1000+ серверов но разработку POC можно
было вполне начать с Java, Python, Ruby, Node e.t.c. Все это прекрасно устанавливается на
современный Linux.

Тоесть мне кажется тебе надо сосредоточиться именно на решении собственно твоей задачи
копирования данных.

А менеджмент памяти языка С тебя похоронит надолго. Закопаешся просто.

Вот реально когда тебе понадобиться язык С - это когда например Java/Python уже перестанут успевать
с копированием данных и ты исчерпаешь все возможности их оптимизации. Но этой точки очень
сложно достигнуть. Обычно I/O является первым барьером для достижения ее.

Вот, к примеру, было непонятно кое-что с копированием данных - открыл исходник PostgreSQL и взял код прям оттуда, немного адаптировав под себя.
Сам факт копирования фрагмента кода приводит меня в изумление. Я думаю что копировать без контекста (без глобальных переменны)
нельзя. По моему только язык Форт позволял такое делать. Для языка С таким глобальным контекстом
по любому будет память, переменные библиотеки и объекты ОС. Поэтому то что ты копировал нужно
подвергнуть code-review.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129841
Фотография Alex_Ustinov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ,

если "Hello word!" в консоли - то имхо ничего не надо
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129850
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Alex_Ustinov
пропущено...
компоненты, библиотеки времени выполнения. Без Runtime код работать не будет
Условно
Для Java - это JRE
Для C# - .NET
и т.д.


Звучит довольно мерзко.


А разве для выполнения скомпилированного exe файла на С# требуются какие-то запущенные процессы в ОС?

И для С это надо, и для С++.

Только это не отдельные процессы, библиотеки работающие в твоем процессе, если упрощенно DLL. Ты против использования DLL?
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129853
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Кстати, правильлно ли я понял что количество столбцов массива надо обязательно через константу присваивать, а количество строк можно из константы вывести в переменную?

Т.е. K вывести в переменную:

Код: plaintext
1.
2.
3.
#define K 2 //количество строк
#define M 3 //количество столбцов
#define N 100 // максимальная длинна строки


У тебя динамическое выделение памяти, можешь заменить константы на переменные.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129854
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
Добавил проверку выделилась ли память при аллокации, надеюсь верно написал:



Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
	char*** stroka = (char***)malloc(K*sizeof(char**));
    if (NULL == stroka) {printf("Memory does not given.\n");return 1;}
for(x=0;x<K;x++)
{
	//выделение памяти для 2-мерного массива
    stroka[x] = (char**)malloc(M*sizeof(char*));
	if (NULL == stroka[x]) {printf("Memory does not given.\n");return 1;}
    for(i=0;i<M;i++)
    {
		//выделение памяти для 1-мерного массива
        stroka[x][i] = (char*)malloc(N*sizeof(char));
		if (NULL == stroka[x][i]) {printf("Memory does not given.\n");return 1;}
    }


}


Правильно, но учти что при срабатывании ранее выделенная память у тебя не освободится, а будет хз в каком состоянии и по хорошему при такой сработке надо совсем завершать работу всего приложения.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129857
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mayton
Вот, к примеру, было непонятно кое-что с копированием данных - открыл исходник PostgreSQL и взял код прям оттуда, немного адаптировав под себя.

Сам факт копирования фрагмента кода приводит меня в изумление. Я думаю что копировать без контекста (без глобальных переменны)
нельзя. По моему только язык Форт позволял такое делать. Для языка С таким глобальным контекстом
по любому будет память, переменные библиотеки и объекты ОС. Поэтому то что ты копировал нужно
подвергнуть code-review.
Я так подозреваю это был пример работы с либой libpq на С. Я так понял это либа для работы из С напрямую с PostgreSQL . Погуглил, примеры на С везде, как понимаю отсюда и родилось требование использовать С.

PS Если так, то С++ тоже справится, код править не придется.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129865
Basil A. Sidorov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Уткъ
А разве для выполнения скомпилированного exe файла на С# требуются какие-то запущенные процессы в ОС?
Вы не поверите, но "скомпилированному файлу" нужны (внешние) динамически компонуемые библиотеки (.dll/.so).
А линуксоиды не понимают своего счастья и до сих пор не включили Mono/NetCore в базовые компоненты своих дистрибутивов.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129884
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mayton

А менеджмент памяти языка С тебя похоронит надолго. Закопаешся просто.


Есть такое, с массивом не думал что будет так сложно. Планировал массив создать за час максимум )




mayton

Вот реально когда тебе понадобиться язык С - это когда например Java/Python уже перестанут успевать
с копированием данных и ты исчерпаешь все возможности их оптимизации. Но этой точки очень
сложно достигнуть. Обычно I/O является первым барьером для достижения ее.


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



mayton

Сам факт копирования фрагмента кода приводит меня в изумление. Я думаю что копировать без контекста (без глобальных переменны)
нельзя. По моему только язык Форт позволял такое делать. Для языка С таким глобальным контекстом
по любому будет память, переменные библиотеки и объекты ОС. Поэтому то что ты копировал нужно
подвергнуть code-review.


Да, конечно, я там переменные подправил, мне нужно было понять сам принцип, примеров не было, в итоге скопировал из исходника строчек 5 и переделал их под себя. )
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129886
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alex_Ustinov
Уткъ,

если "Hello word!" в консоли - то имхо ничего не надо


Хеллоу ворд - это вчерашний день.

А точнее я его еще на прошлой неделе сделал :-)
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129887
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Ты против использования DLL?


нет.

я просто думал что там какая-нить служба\демон должны были крутиться чтобы работало.
...
Рейтинг: 0 / 0
Си. Освободить память 2-мерного сторкового массива
    #40129888
Уткъ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Dima T
Уткъ
Кстати, правильлно ли я понял что количество столбцов массива надо обязательно через константу присваивать, а количество строк можно из константы вывести в переменную?

Т.е. K вывести в переменную:

Код: plaintext
1.
2.
3.
#define K 2 //количество строк
#define M 3 //количество столбцов
#define N 100 // максимальная длинна строки


У тебя динамическое выделение памяти, можешь заменить константы на переменные.


Супер!
...
Рейтинг: 0 / 0
25 сообщений из 308, страница 3 из 13
Форумы / C++ [игнор отключен] [закрыт для гостей] / Си. Освободить память 2-мерного сторкового массива
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]