C - Как найти размер структуры? - PullRequest
0 голосов
/ 12 декабря 2011

В c, скажем, у вас есть следующая структура и экземпляр этого:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    typedef struct _a {
        int *a1;
        float *a2;
        char *a3;
    }a;

    a b;
    b.a1 = (int *) malloc(sizeof(int) * 10);
    b.a2 = (float *) malloc(sizeof(float) * 10);
    b.a3 = (char *) malloc(sizeof(char) * 10);

    return 0;
}

Теперь, как найти общий объем памяти, выделенный / связанный с переменной b? sizeof (b) просто возвращает объединенный размер указателей в структуре, но не вычисляет сумму памяти, которая была выделена с помощью malloc для разных типов / размеров. Как найти общий размер этой структуры в памяти (включая заполнение, если применимо)?

Ответы [ 5 ]

5 голосов
/ 12 декабря 2011

Стандартного способа не существует.

Если вы хотите узнать, сколько памяти хранится в каждом из указанных массивов, вам необходимо явно записать эту информацию в своей структуре, например:

typedef struct _a {
    int *a1;
    float *a2;
    char *a3;
    size_t num_elements_a1;
    size_t num_elements_a2;
    size_t num_elements_a3;
}a;
4 голосов
/ 12 декабря 2011

Вам придется самостоятельно отслеживать совокупный размер вашей структуры.

Инфраструктура C не знает, какая память выделена для каких указателей.Даже создание строгой обобщенной концепции «владения» памятью указателем чрезвычайно сложно.

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

В этом случае подсчет памяти может стать невероятно трудным.Если два разных элемента указывают на одну и ту же память, следует ли считать ее дважды или один раз?Какая система будет отслеживать, какая память считается или не учитывается?Как эта система вписалась бы в минималистскую парадигму C?

Чтобы сделать то, что вы просите, я думаю, вам нужен язык с отражением / самоанализом, такой как Java или .Net (C #).

2 голосов
/ 12 декабря 2011

sizeof() примет во внимание необходимые отступы. Однако это не «глубокий» sizeof, что означает, что он не будет следовать указателям / ссылкам и не будет включать в себя размеры объектов, на которые указывают, включая массивы a1 ... a3 в ваш пример.

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

1 голос
/ 12 декабря 2011

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

0 голосов
/ 12 декабря 2011

Очень очень НЕТ стандартный способ сделать это - выяснить, как работает ваша система malloc. Это работает на большинстве Linux

Вы берете указатель, который дал вам malloc, и перемещаете обратно sizeof (ptr) - здесь хранится значение, обычно равное размеру блока памяти, зарезервированного в вызове malloc.

Выполнение этого аннулирует все гарантии, хотя я бы использовал его только для отладки. Хотя лучше хранить это значение, когда вы используете malloc памяти.

...