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

#include
#include

struct abc
{
        int *x;
};

int main()
{

        struct abc *p = (struct abc*)malloc(sizeof(struct abc));
        p->x = (int*)malloc(sizeof(int));
        p->x = 10;
        printf("The value is %d\n",p->x);
        free(p);
}

Сейчас я получаю результат в соответствии с моими ожиданиями, но при компиляции я получил предупреждающее сообщение.

temp.c:14:7: warning: assignment makes pointer from integer without a cast [enabled by default]
temp.c:15:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat]

Я также пробовал,

*p->x = 10
 printf("The value is %d\n",*p->x);

но это не работает.

Как решить эту проблему?

space earth

Ответов: 5

Ответы (5)

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

*p->x = 10;

При выделении памяти нет необходимости приводить возврат malloc. malloccalloc, и т.д.) возвращает не что иное, как адрес памяти, который не имеет типа (или имеет тип void). Кроме того, когда вы используете 'sizeof object', вы устраняете риск ошибки в указании типа (это становится более очевидным, когда используются typedef и т.д.). Например, ваши распределения должны быть просто:

struct abc *p = malloc (sizeof *p);
p->x = malloc (sizeof *p->x);

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

Необходимо использовать программу проверки ошибок памяти, чтобы убедиться, что вы не записали данные за пределы выделенного блока памяти, не пытались прочитать или выполнить переход на основе неинициализированного значения, и, наконец, чтобы убедиться, что вы освободили всю выделенную память. И это то, что вам не удается сделать. Если вы выделили ее, освободите ее, когда она больше не нужна. Например:

free (p->x);
free (p);

Существует множество тонких способов неправильного использования нового блока памяти. Использование программы проверки ошибок памяти позволяет выявить любые проблемы и проверить правильность использования выделенной памяти, а не обнаружить проблему через segfault. Для Linux valgrind является обычным выбором программы проверки ошибок памяти. Существуют аналогичные программы проверки памяти для каждой платформы. Все они просты в использовании, просто прогоните свою программу через него. Например:

$ valgrind ./bin/struct_simple
==21079== Memcheck, a memory error detector
==21079== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al.
==21079== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info
==21079== Command: ./bin/struct_simple
==21079==

 The value is 10

==21079==
==21079== HEAP SUMMARY:
==21079==     in use at exit: 0 bytes in 0 blocks
==21079==   total heap usage: 2 allocs, 2 frees, 12 bytes allocated
==21079==
==21079== All heap blocks were freed -- no leaks are possible
==21079==
==21079== For counts of detected and suppressed errors, rerun with: -v
==21079== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2)

Вы хотите убедиться, что Все блоки кучи были освобождены - утечки невозможны и ERROR SUMMARY: 0 ошибок из 0 контекстов

Удачи в кодинге в новом году.

Измените две строки следующим образом:

*p->x = 10;

printf("The value is %d\n",*p->x);

это сработает..

Единственное, что здесь есть - это опечатка -

*p->x= 10               /* <-- missing ;  */
printf("The value is %d\n",*p->x);

а также free(p->x) перед освобождением p .

Рабочий пример

"p->x" can hold only address of an integer as it is a pointer. So instead of value assign address to it.

struct abc
{
        int *x;
};

int main()
{
        int i = 10;
        struct abc *p = (struct abc*)malloc(sizeof(struct abc));
        p->x = (int*)malloc(sizeof(int));
        p->x = &i;
        printf("The value is %d\n",*p->x);
        free(p);
}

Попробуйте это:

#include
#include

struct abc
{
        int *x;
};

int main()
{

        struct abc *p = (struct abc*)malloc(sizeof(struct abc));
        p->x = (int*)malloc(sizeof(int));
        int i=10; 
        p->x = &i; //or *p->x = 10; 
        printf("The value is %d\n",*(p->x));
        free(p);
}

Проблема была в том, что вы присваивали значение 10 указателю, и он воспринимал его как адрес, а не как значение, и вы пытались вывести адрес, используя %d, поэтому компилятор выдавал предупреждение. Чтобы устранить это, сначала вам нужно отменить ссылку на член структуры, который является целочисленным указателем, теперь вам нужно отменить ссылку на целочисленный указатель, чтобы присвоить значение.Или вы можете взять одно целое число и сохранить его, как:

p->x = &i.

Доступ к указателю, который является членом структуры, через указатель структуры выше - это правильный способ.

2022 WebDevInsider