Динамические массивы в C ++ - PullRequest
2 голосов
/ 30 января 2011

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

Вот моя функция:

int getSizeOfPointerArray(int a[]){
    int n=0;
    while(true){
        if(!a[n]){
            cout << "a[" << n << "] doesn't exist, breaking" << endl;
            break;
        }
        cout << "a[" << n << "] exists with value " << a[n] << " at memory address " << &a[n] << endl;
        n++;
    }
    return n;
}

Функция была вызвана с аргументом p , где p было:

p = new (nothrow) int[f];

'f' было 3. Элементы массива были собраны с:

for(n=0;n<f;n++){
    string c = ((n!=f-1)?", ":" ");
    cout << p[n] << c;
}

Я ожидал увидеть ячейки памяти трех элементов массива, напечатанных в выходных данных - каждый с четырьмя - и сказать, что [4] не существует. Вместо этого он напечатал шесть адресов памяти. Первые три значения были правильными (все 3 с), но последние три были -33686, -1414812757 и еще -1414812757.

Почему это? Могу ли я просто разделить конечный результат на 2, или не всегда удваивается количество назначенных вами элементов? Это то же самое с нединамическими массивами?

Ответы [ 4 ]

7 голосов
/ 30 января 2011

Когда вы выделяете «массив» с помощью new, вам просто дается какая-то произвольная ячейка памяти, которая в данный момент не используется ничем другим. Эта память (и ее окружение), скорее всего, заполнены случайным мусором и, вероятно, не нулями. Запись известных ненулевых значений в p[0], p[1] и p[2] не повлияет на мусор, который живет только вне p.

Таким образом, ваш цикл просто идет по памяти, пока он либо не достигнет нуля (что, как я полагаю, произошло в этом случае), либо не достигнет памяти, к которой ему не разрешен доступ, что приведет к ошибке сегмента.

Как уже говорили другие, если вы используете C ++, вы должны использовать преимущества контейнерных классов STL. std::vector, вероятно, лучшая замена для простого массива.

5 голосов
/ 30 января 2011

Размер динамически размещаемого массива недоступен для кода C ++, я бы порекомендовал использовать std::vector.

Если массив определен в стеке (например, int arr[2]; или int arr[] = { 1, 2, 3 }), тогда sizeof(arr) будет sizeof(int) * elements_in_arr (даже тогда вы должны использовать std::tr1::array). Если вы хотите иметь дело с массивом, размер которого неизвестен во время компиляции, тогда 101% времени std::vector - это путь (плюс или минус 2 процента).

3 голосов
/ 30 января 2011

Вы правы.У вас есть указатель на блок памяти, а не на реальный массив.

int getSizeOfPointerArray(int a[]) совпадает с: int getSizeOfPointerArray(int* a), так что в любом случае вы все равно будете передавать указатель на первый элемент в вашем массиве.

То, что вы делаете, - неопределенное поведение.

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

Если у вас естьФактический массив, вы можете сделать что-то с шаблонами, такими как:

template <typename T, size_t N>
size_t getSizeInBytes(const T (&array)[N])
{
    return N * sizeof(T);
}
1 голос
/ 30 января 2011

Самое простое решение - использовать векторный тип в STL. Он имеет встроенные функции, которые позволяют получить длину вектора. Размер - это просто длина, умноженная на sizeof () одного элемента.

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