C ++ программирование, динамическая память не работает должным образом, используя malloc и calloc - PullRequest
2 голосов
/ 18 мая 2019

Я только начал изучать C ++, и у меня возникла проблема, которую я не смог найти в Интернете, поэтому я надеюсь, что вы мне поможете.

Это мой код:

int* a;
int* b;

a = (int*)calloc(1, sizeof(int));
b = (int*)calloc(5, sizeof(int));

cout << sizeof(a) << endl;
cout << sizeof(b) << endl;

То, что компилятор возвращает мне: 8, 8. Если я использую:

cout << sizeof(*a) << endl;
cout << sizeof(*b) << endl;

Компилятор возвращает 4, 4.

То же самое относится и к malloc. Я использую.

Что я делаю не так? Почему размер b не равен 20, так как он в 5 раз больше, если int имеет длину 4 байта?

Спасибо!

Ответы [ 3 ]

3 голосов
/ 18 мая 2019

sizeof(*a) и sizeof(*b) всегда будут равны 4. Кажется, вы ожидаете, что они вернут размер массивов, но вы должны понимать, что a и b не массивов.Они являются указателями на int.Если sizeof(int) равно 4, то sizeof(*a) также будет равно 4, и это уже известно во время компиляции.

С учетом вышесказанного вам не нужно использовать функции библиотеки C malloc() и calloc() в C ++.Если вам нужно ручное выделение памяти, используйте new и delete:

a = new int;
b = new int[5];

Если вам нужно выполнить инициализацию нуля, как это делает calloc, просто используйте () для построения по умолчанию выделенногоцелые числа:

a = new int();
b = new int[5]();

Вместо free() используйте delete или delete[], в зависимости от того, как new был вызван ранее:

delete a;    // Note: no '[]'
delete[] b;  // Needs '[]'

Однако вы ненужно ручное распределение памяти здесь.Просто используйте std::vector<int>:

#include <vector>
// ...

std::vector<int> a(5); // 5 int elements, zero-initialized.
std::cout << a.size() << '\n'; // Will print '5'.

Как правило, ваш код C ++ не должен вызывать new, delete, malloc(), calloc() или free().Ручное управление памятью требует больше кода и подвержено ошибкам.Вместо этого используйте контейнеры, такие как vector, и интеллектуальные указатели, такие как shared_ptr и unique_ptr, чтобы уменьшить вероятность утечки памяти и других ресурсов.Эти более безопасные типы также более удобны.Например, с vector вам не нужно запоминать размер выделенной памяти самостоятельно.vector отслеживает его размер для вас.Вы также можете легко копировать векторы, просто назначая их напрямую.Вам также не нужно delete или free() векторов вручную.Они автоматически удаляются при выходе из области видимости.

В качестве дополнительного примечания я рекомендую избавиться от привычки использовать endl для печати новых строк.endl очищает поток, он не просто печатает новую строку.Если вы используете его, вы будете постоянно очищать поток вывода, что является медленной операцией.Вам редко нужно очищать поток, и в этом случае вы можете просто сделать это вручную с помощью << flush, если необходимость когда-либо возникнет.

0 голосов
/ 18 мая 2019

sizeof(a) - размер указателя (обычно это 8 в 64-битной архитектуре), а sizeof(*a) - размер указанного элемента (целочисленное значение). Ничто не возвращается оператором sizeof, имеет динамическую природу (как число элементов, возвращаемых calloc(3))

Кстати, calloc() сильно не рекомендуется в C ++. Его использование зарезервировано для случаев, когда вы должны передать указатели на код C и для унаследованного кода. Используйте операторы new и new [] (последний в этом случае). Но ничего из этого не изменится, оператор sizeof продолжит возвращать полученные значения. Если вы хотите проверить размер возвращаемого массива, то проверьте параметры, переданные обоим операторам.

0 голосов
/ 18 мая 2019

Вы берете размер указателя в первом случае и размер элемента во втором. * a для ваших намерений и целей совпадает с [0]. Размер указателя зависит от архитектуры, а размер int равен 4.

Значение sizeof оценивается во время компиляции. Динамическое выделение памяти происходит во время выполнения. Чтобы узнать сумму, выделенную во время выполнения, вы можете посмотреть на перегрузку нового оператора (не рекомендуется) или на использование контейнеров, как предлагалось в комментариях.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...