Получение размера члена класса в C ++ - PullRequest
3 голосов
/ 22 октября 2019

Я создал класс с именем IntSet. Моя проблема в том, что я не хочу хранить другой элемент, который представляет собой максимальное количество элементов, которые я хочу ввести в массив elem. Итак, в методе add или любом другом методе я хочу узнать максимальный размер, который я выделил в конструкторе IntSet (int dim_max), используя эту операцию:

int n = sizeof(elem) / sizeof(*elem); //or sizeof(elem) / sizeof(int);
cout << "N is = " << n;

Однако это не работает, каждый раз n1, даже если я выделю elem = new int[dim_max];, где dim_max - это переменная, которую я читаю с клавиатуры, и она намного больше 1. Вот код:

 #include <iostream>
using namespace std;

class IntSet{
    int *elem;
    int dim;

    public:

    IntSet (int dim_max) {
        dim = -1;
        elem = new int[dim_max];
    }

     void add(int new_el) {
        int n = sizeof(elem) / sizeof(int);
        cout << "N is =" << n;
        for(int i = 0; i < n; i++) {
            if(elem[i] == new_el) {
                cout << "It's already there !";
                return;
            }
        }
        dim++;
        if(dim == n) {
            elem = (int*)realloc(elem, sizeof(int) * (n + 1));
            global_var++;
        }
        elem[dim] = new_el;
     }
};

Ответы [ 4 ]

4 голосов
/ 22 октября 2019

Оператор sizeof работает с типами во время компиляции. Поскольку elem является int*, sizeof(elem) совпадает с sizeof(int*). И *elem - это int, поэтому sizeof(*elem) - это sizeof(int).

Таким образом, в итоге ваша формула эквивалентна sizeof(int*)/sizeof(int), независимо от того, что вы положили в elem. Не существует стандартного способа узнать количество элементов массива, которое было выделено для указателя.

Для вашей цели вы либо должны отслеживать dim_max в своем классе, либо, что лучше, заменить использование указателей и массивов на более приятные vector.

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

2 голосов
/ 22 октября 2019

Это потому, что elem является указателем. Таким образом, каждый раз, когда вы делаете sizeof(elem) или sizeof(*elem);, вы получите размер типа данных и указателя соответственно.

Если вы не использовали динамическое распределение, тогда ответ будет ОК.

Я бы предложил вам использовать контейнер STL или хранить максимальный размер в качестве элемента данных.

2 голосов
/ 22 октября 2019

elem - указатель, а sizeof(ptr) всегда фиксирован. На 32-битной машине размер указателя составляет 32 бита (4 байта), а на 64-битной - 8 байт. Независимо от того, на какой тип данных они указывают, они имеют фиксированный размер.

Таким образом, вычисление, которое вы выполняете sizeof(elem)/sizeof(*elem), всегда будет давать 1, поскольку оно совпадает с sizeof(int). Это будет работать, если elem является массивом с заранее заданным размером. Чтобы отслеживать текущий размер, вам нужна другая переменная.

Другое дело, не смешивайте new и realloc. Всегда используйте new, как вы используете C ++.

0 голосов
/ 22 октября 2019

Первым делом сначала вы делите два не двойных значения, поэтому результат не соответствует ожидаемому. 12/8 равно 1.

размер указателя в зависимости от архитектуры равен 8 или 4.

Вы думаете, sizeof возвращает размер массива, который имеет место только для автоматических массивов, а не динамических.

...