LINUX.ORG.RU

Чем чревата прямая инкапусляция структур в си?

 


0

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

typedef struct
{
   int a;
   char b;
   char c[20];
} TypeA;

typedef struct
{
  TypeA ta;
  int d;
} TypeB;

int main(void)
{
   /* Без проверок на аллокацию, суть не в них */
   TypeA * ta = malloc(sizeof(TypeA));
   ta->a = 5;   

   TypeB * tb = realloc(ta, sizeof(TypeB));
   tb->ta.b = 6;

   printf("%d, %d\n", tb->ta.a, tb->ta.b);

   free(tb);

   return 0;
}

UB?

★★★★★

Ответ на: комментарий от f1u77y

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

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Что значит расширить? Типа наследование полиморфизм?

И хотя ты сказал что проверки не важны — free(tb) не освободит ta, но ты и так это должен знать. Т.е. в любом случае нужны какие-то «конструкторы» и «деструкторы» для каждого типа, с учетом кто там в ком находится.

Иначе вообще не понятно чего ты хочешь.

deep-purple ★★★★★
()
Последнее исправление: deep-purple (всего исправлений: 1)
Ответ на: комментарий от deep-purple

free(tb) не освободит ta

realloc освободил уже ta

anonymous
()
Ответ на: комментарий от deep-purple

free(tb) не освободит ta

Что-то мне подсказывает, что вы ошибаетесь. ta был реаллоцирован и стал tb. Так что физически это один и тот же указатель (а если повезет с последовательным местом, то даже значение не изменится).

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

typedef struct
{
   int a;
   char b;
   char c[20];
} TypeA;

typedef struct
{
  TypeA ta;
  int d;
} TypeB;

int main(void)
{
   /* Без проверок на аллокацию, суть не в них */
   TypeA * ta = malloc(sizeof(TypeA));
   printf("%X\n", ta);
   ta->a = 5;   

   TypeB * tb = realloc(ta, sizeof(TypeB));
   printf("%X\n", tb);
   tb->ta.b = 6;

   printf("%d, %d\n", tb->ta.a, tb->ta.b);

   free(tb);

   return 0;
}
sh-4.2$ main                                                                                                                                          
602010                                                                                                                                                
602010                                                                                                                                                
5, 6   

Иначе вообще не понятно чего ты хочешь.

Есть некая либа-фреймворк. Реализует бОльшую часть функционала через плагины-библиотеки. Есть один плагин «A», который аллоцирует TypeA. Мой плагин - суть расширение функционала плагина «A». Поэтому я вызываю аллокатор плагина «А», потом реаллоцирую до свого размера. В своем деструкторе сначала подчищаю свой мусор, потом вызываю деаллокатор плагина «А».

PPP328 ★★★★★
() автор топика
Ответ на: комментарий от PPP328

Открою тебе маленькую тайну: UB или не UB определяется не скором говорящего, а стандартом C.

anonymous
()

Причем тут инкапсуляция?

anonymous
()
Ответ на: комментарий от ProstoTyoma

Тем, что код плагина «А» менять нельзя.

PPP328 ★★★★★
() автор топика

Чем чревата прямая инкапусляция структур в си?

инкапсуляция

в си

Ручной реализацией ООП, таблиц виртуальных функций и долгими беседами с психотерапевтом«еще одним убийцей С++»(ТМ)

slackwarrior ★★★★★
()
Ответ на: комментарий от deep-purple

И хотя ты сказал что проверки не важны — free(tb) не освободит ta, но ты и так это должен знать.

Там до освобождения идет tb = realloc(ta).

andreyu ★★★★★
()
Ответ на: комментарий от ProstoTyoma
TypeB * tb = malloc(sizeof(TypeB));
tb.ta = *ta;


1. tb->ta = *ta;
2. в чем смысл конструкции?

andreyu ★★★★★
()

Нормально всё будет, хотя и не очень красиво. В винде повсеместно такие костыли.

Красиво будет, если твоя либа, работающая с TypeA, умеет использовать аллоцированные тобой структуры, а не только аллоцировать самостоятельно. Тогда делаешь свою структуру TypeB соcтоящую из полей TypeA + свои поля, аллоцируешь сам, инициализируешь либой и пользуешь её вместо TypeA в либе.

Stanson ★★★★★
()
Ответ на: комментарий от slackwarrior

Ручной реализацией ООП, таблиц виртуальных функций и долгими беседами с психотерапевтом«еще одним убийцей С++»(ТМ)

Привет :-) Это ты любитель зачёркнутых вставок текста, гайдлайнов и тимлидов в тапках? :-)

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.