C динамическое выделение памяти и sizeof () - PullRequest
1 голос
/ 31 марта 2011

У меня возникли проблемы с пониманием разницы между этими двумя сегментами кода: Я выделяю пространство для массива целых чисел динамически в моем коде с помощью следующего оператора

int *arr = calloc(cnt, sizeof(int));

В другой функции, где я передаю в arr, я бы хотел определить размер (количество элементов) в arr. Когда я звоню

int arr_sz = sizeof(arr)/sizeof(int);

он возвращает только 1, то есть просто число байтов в int для обоих аргументов, которые я предполагаю (4/4) = 1. Я просто предположил, что это будет так же, как использование массива

  int arr[8];
  int arr_sz = sizeof(arr)/sizeof(int);

, который возвращает фактическое количество элементов в массиве.

Если бы кто-нибудь мог это прояснить, это было бы здорово. Спасибо!

Ответы [ 7 ]

8 голосов
/ 31 марта 2011
int *arr;   ----> Pointer
int arr[8]; ----> Array

Прежде всего, что у вас есть - int *arr это указатель, указывает на некоторые байты ячейки памяти, не массив.

Тип для Array и Pointer не совпадает .

В другой функции, в которой я передаю arr, я бы хотел определить размер (число элементов) в arr.Когда я вызываю

int arr_sz = sizeof(arr)/sizeof(int);

, он возвращает только 1, что является просто числом байтов в int для обоих аргументов, которые я предполагаю (4/4) = 1.Я просто предположил, что это будет то же самое, что использование массива

Даже если это предполагается до быть массивом - это потому, что массивы распадаются науказатели при передаче в функции.Вам необходимо явно передать размер массива в функции в качестве отдельного аргумента.

Пройдите через это:

Размер массива на языке программирования C?

Существует разница между массивом static и динамическим распределением памяти.

Оператор sizeof не будет работать с динамическими распределениями.AFAIK лучше всего работает со стековыми и предопределенными типами.

2 голосов
/ 31 марта 2011

ну, int *arr объявляет указатель, переменную, которая хранит адрес какой-то другой переменной, а ее размер равен размеру целого числа, потому что это указатель, ему просто нужно сохранить адрес, а не сам указатель.
int arr[8] объявляет массив, набор целых чисел.sizeof(arr) относится к размеру всей коллекции, поэтому 8 * sizeof (int).
Часто вы слышите, что "массив и указатели - это одно и то же".Это не правда!Это разные вещи.

1 голос
/ 31 марта 2011

Mike,

arr - это указатель, и поэтому, по крайней мере, в вашей системе имеет такое же количество байтов, что и int.Массивы не всегда совпадают с указателями на тип массива.

0 голосов
/ 31 марта 2011

Вы не можете использовать sizeof с указателями памяти:

int *arr = calloc(cnt, sizeof(int));

Но можно использовать его с массивами:

int arr[8];
0 голосов
/ 31 марта 2011

Если у вас есть int arr1[8], то тип arr1 (в том, что касается компилятора) представляет собой массив размером 8 *.

В примере int * arr2 тип arr2 является указателем нацелое число.

sizeof(arr1) - размер массива int
sizeof(arr2) - размер указателя int (4 байта в 32-битной системе, 8 байтов в 64-битной системе)

Таким образом, единственное различие заключается в типе, который компилятор считает этой переменной.

0 голосов
/ 31 марта 2011

*arr - это не то же самое, что arr[8], поскольку его размер не известен во время компиляции, а sizeof является функцией компилятора.Таким образом, когда ваш arr равен *arr sizeof вернет размер указателя (sizeof(int *)) в байтах, а когда ваш arr равен arr[8], sizeof вернет размер массива из 8 целых чисел в байтах(which is sizeof(int) * 8).

Когда вы передаете указатель на массив функции, вы должны указать его размер, потому что компилятор не может сделать это за вас.Другой способ - завершить массив нулевым элементом и выполнить цикл while.

0 голосов
/ 31 марта 2011

sizeof(arr) совпадает с sizeof(int*), то есть размер одного указателя.Однако вы можете рассчитать arr_sz как ... cnt!

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