Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Как определить размер массива?


Автор: Plamenk 16.5.2005, 11:36
Всем Привет!

Возник такой вопрос как можно определить размер динамически создоваемого массива, т.е. например я создаю динимический массив:

Код

int *mas = new int[20];


И как можно определить его размер имея только указатель на него!

Заранее БОЛЬШОЕ СПАСИБО!

Автор: srd 16.5.2005, 11:45
Через указатель размер массива получить нельзя. Хранить/передавать размер нужно самостоятельно.

Автор: Plamenk 16.5.2005, 11:57
Спасибо srd!

Тогда такой вопрос:
Предположим у меня есть класс обертка для массива int.
И мне надо перегрузить оператор = для присваивания массива:

Код

class CDynamArray  
{
public:
    void ChangeSize(int newSize);
    inline int GetLenght() {return m_size;}
    inline void SetValue(int index, int value) {m_array[index] = value;}
    inline int GetValue(int index) {return (m_array[index]);}

    //Перегрузка операторов
    int& operator[](int index){return m_array[index];}
    CDynamArray& operator+=(int size)
    {
        this->ChangeSize(m_size + size);
        return *this;
    }

    CDynamArray& operator-=(int size)
    {
        this->ChangeSize(m_size - size);
        return *this;
    }

    CDynamArray& operator=(int array[])
    {
        int size = sizeof(array)/sizeof(array[0]);
        m_size = size;
        delete[] m_array;

        m_array = new int[size];
        memcpy(m_array, array, size);

        return *this;
    }

    CDynamArray(int size, int value);
    virtual ~CDynamArray();
private:
    int* m_array;
    int m_size;
    int m_value;
};

И соответственно чтобы всё заработало мне надо определить размер массива, либо как-то передать его в функцию?

Автор: Plamenk 16.5.2005, 12:09
Всё!
Вопрос снят я просто не правильно понял задание!

Автор: srd 16.5.2005, 12:13
Ну например, так:
Код

#include <tchar.h>
#include <windows.h>

class A
{
public:
    
    template<size_t SIZE>
    const A& operator =(int (&array)[SIZE])
    {
        // Тут SIZE можно использовать для определения количества элементов в массиве.
        return *this;
    }
};


int WINAPI _tWinMain(HINSTANCE,HINSTANCE,LPTSTR,int)
{
    A a;
    int p[5];
    a = p;

    return 0;
}

Но подсунуть такому оператору вместо массива указатель не получится.

Автор: Plamenk 16.5.2005, 12:24
У меня данный код выдает ошибки

error C2265: '<Unknown>' : reference to a zero-sized array is illegal
error C2679: binary '=' : no operator defined which takes a right-hand operand of type 'int [5]' (or there is no acceptable onversion)

MSVC++ 6.0.

Автор: srd 16.5.2005, 12:27
Я этот код проверял в MSVC++ 7.1. Шестёрка старенькая и не дружит с шаблонами.

Автор: Plamenk 16.5.2005, 12:33
Интересно!
А как компилятор определяет размер массива с помощью template<size_t SIZE>?
Что это - template<size_t SIZE> значит?

Автор: srd 16.5.2005, 12:46
Это называется "шаблон". Так на пальцах тяжело объяснить, попробуй почитать какой-нибудь букварь по Си++.

Автор: Гость_Dov 16.5.2005, 23:18
Цитата(Dov @ 24.11.2003, 20:46)
Цитата(gray_k @ 24.11.2003, )
int *i = new int[MY_SIZE];
Как потом написать конструкцию, которая вернула бы MY_SIZE?
sizeof(i) и sizeof(*i) возврашают 4 байта - размер целой переменной.

size_t size = _msize(i);
_msize возвращает размер (в байтах) выделенного (динамически) блока памяти.
Стало быть MY_SIZE == size / sizeof(int).

dsfff

Автор: Fixin 16.5.2005, 23:23
Цитата
size_t size = _msize(i);
А аналог для Вин32?

Автор: srd 17.5.2005, 08:42
_msize - это MS specific.

Автор: Dov 17.5.2005, 18:37
Цитата(srd @ 17.5.2005, 08:42)
_msize - это MS specific.
Возможно.
Или такой вариант
Код
int *mas = new int[20];
// количество элементов динамического массива типа int
int size = mas[-4] / sizeof(int);


Автор: Fixin 17.5.2005, 18:56
Это откуда?

Автор: Dov 17.5.2005, 19:24
Уже не помню, давно дело было.

Автор: bel_nikita 18.5.2005, 08:39
а может стоит использовать std::vector<int>?
тогда и проблем определить размерность динамического массиса не будет smile

Автор: yaja 18.5.2005, 10:32
Я где-то читал, что когда создается массив, то перед указателем на его первый элемент записывается информация о размере этого массива (поэтому очень важно удалять массив оператором delete[], а не просто delete).
Наверное сдесь
Цитата
int *mas = new int[20];
// количество элементов динамического массива типа int
int size = mas[-4] / sizeof(int);

мы и получаем это значение. smile

Автор: Fixin 18.5.2005, 18:23
Учитывая существование delete и delete[], то определенно, что информация об указателе где-то хранится.
Причем в секрете smile

Автор: Dov 18.5.2005, 21:08
Если не ошибаюсь, то информация о размере такого массива хранится в 16 байтах(имхо, может отличаться на разных машинах), предшествующих нулевому элементу, т. е. для
Код
short * mas = new short[20];
нужно так
Код
int size = mas[-8];
а для
Код
char * mas = new char[20];
так
Код
int size = mas[-16];

Автор: srd 18.5.2005, 21:26
Мож я надоедливый, но, опять-таки, нехорошо полагаться на такие вещи smile Никто не обязывает производителя компилятора хранить размер массива перед его указателем. Поэтому это может быть по разному в разных компиляторах, в разных версиях одного компилятора или даже в разных целях (например, debug или release), созданных одним и тем же компилятором. Или может зависить от версии CRT.

Автор: Dov 18.5.2005, 22:02
srd, а никто и не спорит, это просто информация для общего развития, может быть кому-то пригодится. smile smile smile

Автор: gepard 20.5.2005, 08:31
Согласен с srd.
Просто, кол-во элементов надо всё время с собой таскать...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)