Разница между утверждениями заключается в том, что нет смысла пытаться указать тип указателя в левой части выражения, что вы и делаете в случае (int*)p->data
, поскольку p->data
всегда void*
, как определено в структуре. Когда компилятор видит это, он предполагает, что вы приводите его к int*
, чтобы вы могли прочитать его, то есть оно становится r-значением, значением, которое допустимо только в правой части выражения присваивания, а не значение l (левая сторона), которому можно присвоить.
Если вы хотите прочитать / записать целочисленное значение, хранящееся в p->data
, то я думаю, что самый ясный синтаксис - *((int*)(p->data))
- т.е. возьмите указатель p->data
, приведите его к int*
и затем разыменуйте это - Я уверен, что вы можете потерять некоторые из скобок из-за правил приоритета.
data
- пустой указатель; его не волнует, что вы храните в нем, т. е. ваше (int*)
приведение к malloc эффективно теряется; его волнует только то, что вы дали ему выделенную память.