Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.55/20: Рейтинг темы: голосов - 20, средняя оценка - 4.55
 Аватар для dioxidin
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544

Вопрос по работе с "CALLOC()"

30.08.2008, 19:05. Показов 4197. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Понадобилось сделать несколько функций для работы с массивами разных размеров. Функции выглядят римерно так:
C++
1
2
3
4
5
6
7
8
void SomeFunc(double **Arg, int R, int C)
{
    for(int i=0;i<R;i++) {
         for(int j=0;j<C;j++) {
               // Че-то-там
         }
    }
}
Перед вызовом функций нужно создать указатель. Потом выделить под него память. Я это делаю вот так:
C++
1
2
3
4
5
6
7
8
void MatrixAlloc(double **T,int R,int C)
{
    T = (double**) calloc(R, sizeof(double));
    for(int i = 0; i < R; i++){
      T[i] = (double*) calloc(C, sizeof(double));
      for(int j = 0; j < C; j++) T[i][j] = 0;
    }
}
То есть вызываю эту функцию сразу после объявления переменной "double **Mass;" и жду, что память выделится. Однако получается, что память выделяется внутри MatrixAlloc и невидна вне ее.
??? Можно ли обойти эту проблему? Мне хотелось бы выкинуть из моих других функций код выделения памяти. И вообще избавить программу от десятка копий кода.

ПС: Где-то читал, что код вида "for(int i=0..." нехорошо пользовать. Почему желательно объявлять переменную вне оператора цикла?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
30.08.2008, 19:05
Ответы с готовыми решениями:

malloc vs. calloc
Когда стоит использовать malloc , а когда calloc?

calloc, free.
как правильно выделить память для двумерного массива а, при m=5,n=10 используя функцию calloc. и...

calloc vs malloc
Объясните,пжлста,чем отличается malloc oт calloc?

11
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.08.2008, 21:07
Лучше возвращать указатель из функции.
По поводу инициализации - это для безопасности. На области видимости переменной завязано.
1
 Аватар для dioxidin
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544
30.08.2008, 22:57  [ТС]
Попробую с возвратом указателя сделать. Но я что-то сомневаюсь... Сам-то пробовал?
Я так понял, что нет доступа к выделенной памяти.. а в ком дело - указатель получается невалидный или область видимости памяти нарушена? Если второе, то возврат указателя, думаеццо, не поможет.

Насчет переменной в цикле.. Поясни поконкретнее, пожалуйста.. А то, как я понял, тут суть какая-то очень тонкая.. Вроде в псевдокоде сгенерированный код цикла получается неоптимальный, что-ли, и небезопасный. Но в чем? Переменная эта мне вне цикла не нужна.. Разьве что при дебаге я не могу увидеть последнее значение индекса вне вложенного оператора - ну так это все пустяк. А вот если на какойто операционке может этот код вызвать криминал - тада да..

После Проверки.. Девствительно работает! Как говорят буржуи: "Фенкз ту ю твайс, мэн!!!" Не придется серьезно код править.. Спасиба!

Добавлено через 57 минут 30 секунд
Рещил написать отдельно..
У меня там есть класс.. В его конструкторе я создаю указанным выше способом массивы, а в деструкторе их делетю - в результате имею ошибку дуступа к памяти при закрытии приложения. Если комментирую делеты, то все пучком. Но при этом может быть утечка памяти. Так ли это? Если появляется такая ошибка, то, наверное, память сама очищается (автоматически?).. Но ведь говорят, что аллоки нужно вычищать самому. Я малясь запутался
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.08.2008, 23:17
Блин, конечно пробовал
Будет меняться, если будешь менять значение указателя, а не сам указатель. Сохраняется значение указателя, но не он сам. Ты можешь поменять *ukazatel и оно сохранится, так как, хранится адрес в ukazatel. А сам uakazatel останется таким, какой был до вызова.
Code
1
2
3
4
5
6
7
8
9
10
int* intalloc(int C)
{
    return (int*)malloc(sizeof(int) * C);
}
 
int main()
{
    int *i;
    i = intalloc(10);
    i[5] = 100;
Псевдокод тут не при чем. Просто переменная объявленная в инициализации цикла считается внешней по отношению к самому блоку цикла. То есть, она не внутренняя и не скрытая по отношению ко внешнему от цикла миру.

Добавлено через 1 минуту 27 секунд
А аллоки не "делетят", их освобождают через free.
0
 Аватар для dioxidin
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544
30.08.2008, 23:36  [ТС]
Дружище, уж бональности объяснять не надо мне. Не знаю чем я вызвал подозревание в моей тупости и несведущьности Уж коль я с указателями вожусь, то понимать должон, что они такое есть. Просто опыта маловато, вот и не знаю некоторой специфики. Вот если б спросил типа: "А если я освобожу память через один указатель, а на нее еще один ссылается? Будет ли она освобождена? Тада да.." Ладно... проехали..

Объясни мне, дураку, чем delete и free отличаются.. я имею в виду не синтаксис, канешна
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
30.08.2008, 23:48
Прастите, под всех одновременно сложно подсториться. Если б я увидел тупость, я бы не отвечал в этой теме. У меня есть время и отвечаю развернуто

free освобождает блок памяти, который был до этого выделен с помощью calloc, malloc, realloc.
delete - служит для освобождения памяти выделенной через new.
К слову, тут обсуждалась разница между malloc & new.
Вот тут тоже самое. delete вызывает operator delete. Который, конечно, даже переписать можно. А free просто освободит память.
1
 Аватар для dioxidin
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544
31.08.2008, 00:23  [ТС]
Все пучком, друх! Это я к тому сказал, что можно незаморачиваться на очевидных вещах. Тебе все равно без этого нельзя было обойтись..
Про free понял.. Я как раз на delete и зациклился из-за BDS2006 c VCL. Надо будет отвыкать от некоторых удобств..
Спасибо...
0
Эксперт С++
2924 / 1274 / 114
Регистрация: 27.05.2008
Сообщений: 3,465
31.08.2008, 00:33
Цитата Сообщение от Vourhey Посмотреть сообщение
Просто переменная объявленная в инициализации цикла считается внешней по отношению к самому блоку цикла. То есть, она не внутренняя и не скрытая по отношению ко внешнему от цикла миру.
Гм. Евангелие 14882-2003 (песнь 3.3.2 стих 4) утверждает иное...
0
 Аватар для dioxidin
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544
31.08.2008, 00:42  [ТС]
С free та же петрушка.. Может не надо в деструкторе это ставить?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
31.08.2008, 00:42
CheshireCat, все что объявлено вне внутреннего блока цикла считается внешним относительно его. Следование евангелию может привести к различным последствиям. В любом случае, на это полагаться нельзя. Хотя, компилятор тоже говорит иное.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
31.08.2008, 03:22
Цитата Сообщение от dioxidin Посмотреть сообщение
С free та же петрушка.. Может не надо в деструкторе это ставить?
В каком деструкторе? Что там стоит?

Добавлено через 2 часа 36 минут 43 секунды
Вот немного о for'ах:
https://www.cyberforum.ru/cpp/... #post51823
0
 Аватар для dioxidin
132 / 99 / 11
Регистрация: 21.11.2007
Сообщений: 544
04.09.2008, 16:17  [ТС]
Вот код конструктора класса и его деструктора...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
__fastcall TKalman::TKalman()
{
//  double F[16][16],dF[16][16],Xmk[16],Xk_1[16],Xk[16]/*,Zk[8],Uk_1[3]*/,D[8][8],dD[8][8],C[8][8],dC[8][8],
//         R[16][3],dR[16][3],Rpi[3][16],Pk[16][16],Pmk[16][16],Pk_1[16][16],K[16][8],M[8][16],Mt[16][8],Uk_1[3],Uk[3];
    F = MatrixAlloc(16,16);
    dF = MatrixAlloc(16,16);
    FXk_1 = MatrixAlloc(16,1);
    Xmk = MatrixAlloc(16,1);
    Xk_1 = MatrixAlloc(16,1);
    Xk = MatrixAlloc(16,1);
    Zk = MatrixAlloc(16,1);
    D = MatrixAlloc(8,8);
    dD = MatrixAlloc(8,8);
    C = MatrixAlloc(8,8);
    dC = MatrixAlloc(8,8);
    R = MatrixAlloc(16,3);
    dR = MatrixAlloc(16,3);
    Rpi = MatrixAlloc(3,16);
    Pk = MatrixAlloc(16,16);
    Pmk = MatrixAlloc(16,16);
    Pk_1 = MatrixAlloc(16,16);
    K = MatrixAlloc(16,8);
    M = MatrixAlloc(8,16);
    Mt = MatrixAlloc(16,8);
    dM = MatrixAlloc(8,16);
    Uk = MatrixAlloc(3,1);
    Uk_1 = MatrixAlloc(3,1);
}
__fastcall TKalman::~TKalman()
{
//  double F[16][16],dF[16][16],Xmk[16],Xk_1[16],Xk[16]/*,Zk[8],Uk_1[3]*/,D[8][8],dD[8][8],C[8][8],dC[8][8],
//         R[16][3],dR[16][3],Rpi[3][16],Pk[16][16],Pmk[16][16],Pk_1[16][16],K[16][8],M[8][16],Mt[16][8],Uk_1[3],Uk[3];
    free(F);
    free(dF);
    free(FXk_1);
    free(Xmk);
    free(Xk_1);
    free(Xk);
    free(Zk);
    free(D);
    free(dD);
    free(C);
    free(dC);
    free(R);
    free(dR);
    free(Rpi);
    free(Pk);
    free(Pmk);
    free(Pk_1);
    free(K);
    free(M);
    free(Mt);
    free(dM);
    free(Uk);
    free(Uk_1);
}
MatrixAlloc:
C++
1
2
3
4
5
6
7
8
double **TKalman::MatrixAlloc(int R,int C)
{
    double **T = (double**) calloc(R, sizeof(double));
    for(int i = 0; i < R; i++){
      T[i] = (double*) calloc(C, sizeof(double));
      for(int j = 0; j < C; j++) T[i][j] = 0;
    }
}
Добавлено через 29 минут 50 секунд
Только щас заметил.. У меня эта функция в двух местах (модулях) образовалась.. В одном есть возвращение указателя, а в другом модуле эта функция без возврата. Может в этом касяк? Посмотрю щас.

Добавлено через 2 минуты 4 секунды
Точно так... Вот где собака порылась. КопиПэйст Маст ДАЙ!

ПС: В нескольких модулях у меня для удаления указателей все же использовался delete.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
04.09.2008, 16:17
Помогаю со студенческими работами здесь

calloc
Я, по сути, программист самоучка. Хорошим манерам кодинга не обучен, пишу то, что интересно и по...

Как правильно создать двумерный массив указателей с использованием calloc? и ввод данных в него
Как правильно создать двумерный массив указателей с использованием calloc и ввести в него данные?

Работа с calloc и free в C++
Всем добрый день!! Уважаемые программисты посмотрите пожалуйста, корректно ли я использую эти...

Как string создает строку?(calloc, malloc)
стринг создает строку с помощью calloc, malloc?

Использование calloc/realloc/free
//calloc.cpp //Использование calloc #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;iostream&gt;...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru