Как выделить память внутри структуры и вне основной? - PullRequest
2 голосов
/ 25 апреля 2019

Я новичок в C, и у меня возникают проблемы при попытке выделить память вне основной функции.

Моя цель - создать указатель (который находится внутри моей структуры) int size.Если оно имеет значение NULL, передайте его элементу структуры, и оно должно быть узнаваемым для главной функции.

Я перепробовал все, что мог себе представить, но никогда раньше не чувствовал себя так застрявшим, извините, что не далбольше информации.

struct info {
    int *data;
};

void allocate(struct info *ptr);

int main()
{
    struct info *p;
    struct info a;

    p = &a;
    allocate(p);
    free(p->data);
    return 0;
}

void allocate(struct info *ptr)
{
    if(ptr->data == NULL)
    {
        ptr->data = malloc(sizeof(int));
    }
}

Я ожидаю, что main будет распознавать data как имеющий размер int, и если вы можете помочь мне, как впоследствии освободить тот же указатель, это было бы очень полезно,Спасибо.

Ответы [ 2 ]

0 голосов
/ 25 апреля 2019

Как уже указывалось, ваша структура неинициализирована, поэтому, скорее всего, она не заполнена NULL.Самый простой способ получить нулевую инициализированную структуру в C - это использовать {0}:

struct info a = {0};

. Вы можете исключить дополнительную переменную p, вызвав allocate(&a); напрямую.


В качестве более простого примера:

int main(void) {
    int *p;
    if (p == NULL) { // probably false
      // ...
    }
}

указатель выше не инициализирован.В отличие от других языков (таких как Java), p не гарантированно будет ничем.


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

#include <stdlib.h>

struct info {
  int *data;
};

struct info* new_info(void);
void free_info(struct info* p);


int main(void) {
  struct info *p = new_info(); // user doesn't worry about creation details
  // ... use p ... 
  free_info(p); // user doesn't worry about deletion details
}

struct info* new_info(void) {
  struct info* p = malloc(sizeof *p);
  p->data = malloc(sizeof *p->data);
  return p;
}

void free_info(struct info* p) {
  free(p->data);
  free(p);
}
0 голосов
/ 25 апреля 2019

Это просто невозможно напрямую. Вы не можете получить размер выделенной памяти из возвращенного указателя с помощью функций распределителя.

Лучше всего было бы иметь другую переменную-член для хранения размера выделенной памяти и обновлять ее значением после успешного распределения.

Тем не менее,

if(ptr->data == NULL)

вряд ли будет ИСТИНА, как вы могли ожидать, потому что ptr->data неинициализирован, а содержимое неопределено. В любом случае вы должны ptr->data указать на действительное место в памяти, чтобы проверка не имела никакого значения.

...