Это vali, чтобы позвонить бесплатно с указателем на первый член?
Можно ли бесплатно позвонить по указателю, который указывает на первый член структуры (а структура - та, которая связана с malloc)? Я знаю, в принципе, указатель указывает на правильную вещь в любом случае...
struct s {int x;};
//in main
struct s* test;
test = (struct s*) malloc(sizeof(*test));
int* test2;
test2 = &(test->x);
free(test2); //is this okay??
Также будет изменен ответ, если int x
будет заменен на struct?
Обновление: зачем мне писать такой код?
struct s {int x;};
struct sx1 {struct s test; int y;}; //extending struct s
struct sx2 {struct s test; int z;}; //another
// ** some functions to keep track of the number of references to each variable of type struct s
int release(struct s* ptr){
//if the number of references to *ptr is 0 call free on ptr
}
int main(){
struct sx1* test1;
struct sx2* test2;
test1 = (sx1*) malloc(sizeof(*sx1));
test2 = (sx2*) malloc(sizeof(*sx2));
//code that changes the number of references to test1 and test2, calling functions defined in **
release(test1);
release(test2);
}
Ответы
Ответ 1
Да, это нормально.
6.7.2.1
- Внутри объекта структуры небитовые поля и единицы, в которых бит-поля имеют адреса, которые увеличиваются в том порядке, в котором они объявлены. Указатель на структурный объект, соответствующим образом преобразованный, указывает на его первоначальный член (или если этот элемент является бит-поле, затем в блок, в котором он находится) и наоборот. Может быть неназванный заполнение внутри объекта структуры, но не в начале.
Это означает, что это определено:
struct s {int x;};
struct s* test;
test = (struct s*) malloc(sizeof(*test));
int* p = &(test->x);
free(p);
Ответ 2
В соответствии со стандартом C11, глава §6.7.2.1
[...] Может быть неназванный заполнение внутри объекта структуры, но не в начале.
что означает, что в начале структуры не может быть отступов. Таким образом, первый член будет иметь тот же адрес, что и структурная переменная.
free()
нужен указатель, который ранее был возвращен malloc()
или семейством.
В вашем случае вы передаете тот же адрес, что и malloc()
. Итак, вы хорошо пойдете.