Внедрение против указателя во вложенных структурах типа String - PullRequest
0 голосов
/ 18 апреля 2019

При проектировании структур, содержащих текстовые данные, я использовал два основных подхода, показанных ниже:

typedef struct {
    STRING address1;
    STRING address2;
    STRING city;
    STRING state;
    STRING zip;
} ADDRESS;

typedef struct {
    STRING* address1;
    STRING* address2;
    STRING* city;
    STRING* state;
    STRING* zip;
} ADDRESS;

, где STRING - это некоторый тип хранения строк переменной длины.Преимущество версии указателя состоит в том, что я могу хранить NULL, указывая, что данные отсутствуют.Например, адрес2 может быть не предоставлен для некоторых адресов.В типе со встроенными STRING я должен использовать «пустую» строку, то есть ту, которая имеет длину 0.

С указателями (возможно) больше бремени кода, потому что я должен проверить каждый элемент на NULLПеред использованием.Однако преимущество не так велико, потому что обычно нужно проверять и встроенную версию.Например, если я печатаю адрес, я должен проверить строку нулевой длины и пропустить эту строку.С помощью указателей пользователь может фактически указать, что он хочет «пустое» значение вместо отсутствующего значения, хотя использование этого трудно увидеть.

При создании или освобождении структуры указатели добавляют ряд дополнительных шагов.Мой инстинкт состоит в том, чтобы стандартизировать встроенный стиль, чтобы сохранить эти шаги, но я обеспокоен тем, что может быть скрытая ошибка.Это необоснованный страх, или я должен использовать указатели по какой-то веской причине?

Обратите внимание, что использование памяти является проблемой, но это довольно незначительно.Версия указателя занимает немного больше памяти, потому что я храню указатели на структуры в дополнение к структурам.Но каждая строковая структура занимает в среднем около 40 байт, поэтому, если я храню 4-байтовые указатели, то версия указателя стоит, возможно, на 10% больше памяти, что неважно.Наличие нулевых указателей возможно не экономит значительную память, потому что большинство полей заполнены.

Вопрос касается АДРЕСА, а НЕ STRING

Некоторые респонденты, похоже, смущены и думают, что яЯ прошу о глобальных компромиссах, например, как минимизировать мою общую работу.Это не относится к делу.Я спрашиваю о том, как спроектировать АДРЕС, а не STRING.Члены адреса могут иметь фиксированные массивы, а в других случаях - нет.Для целей моего вопроса меня не волнуют последствия для контейнера.

Я уже говорил, что единственная проблема, которую я вижу, это то, что использование указателей требует больше времени, но я получаюпреимущество возможности хранить NULL.Однако, как я уже сказал, эта выгода не кажется существенной, но, возможно, по какой-то причине.В этом суть моего вопроса: есть ли какая-то скрытая выгода от такой гибкости, которую я не вижу и пожелаю, чтобы она была у меня позже.

Если вы не понимаете вопрос, прочитайте предварительный ответЯ написал себе ниже (после некоторой дополнительной мысли), чтобы увидеть ответ, который я ищу.

Ответы [ 3 ]

2 голосов
/ 18 апреля 2019

Компромисс между использованием памяти и сокращением количества ссылок

Похоже, что компромисс сосредоточен вокруг двух вопросов: 1) Насколько драгоценна память? и 2) Имеет ли значение, что для строк выделяется фиксированный объем памяти, ограничивая длины, которые должны храниться в каждом поле?

Если память важнее всего остального, то, вероятно, победит версия указателя. Если предпочтительна предсказуемость использования хранилища и избежание malloc, и ограничение длины имен до некоторой фиксированной суммы является приемлемым, то версия с фиксированной длиной может быть победителем.

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

Я рассматривал это более глубоко, и я думаю, что в большинстве случаев указатели необходимы, потому что важно различать пустое и отсутствующее.Причина этого заключается в том, что недостающие данные необходимы, когда ввод неверен, поврежден или пропущен.Например, давайте представим, что при чтении из файла файл поврежден, поэтому такое поле, как почтовый индекс, не читается.В этом случае данные «отсутствуют», и указатель должен быть NULL.С другой стороны, давайте представим, что в этом месте нет почтового индекса, тогда оно «пустое».Таким образом, NULL означает, что пользователь еще не предоставил информацию, но пустое означает, что пользователь предоставил информацию, и нет ни одного из рассматриваемых типов.

Итак, чтобы дополнительно проиллюстрировать важность использования указателя,Представьте, что сложная структура заполняется во времени различными асинхронными шагами.Здесь нам нужно знать, какие поля были прочитаны, а какие нет.Если мы не используем указатели (или не добавляем дополнительные метаданные), мы не сможем определить разницу между полем, на которое был получен ответ, и полем, для которого ответ «нет».Представьте себе систему, запрашивающую у пользователя «что такое почтовый индекс?».Пользователь говорит: «У этого места нет почтового индекса».Затем через 5 минут система снова спрашивает: «что такое почтовый индекс?».Этот вариант использования проясняет, что в большинстве случаев нам нужны указатели.

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

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

Одна проблема со встроенным стилем заключается в том, что STRING необходимо определить как что-то вроде char[MAX_CHAR + 1], где MAX_CHAR - пессимистическая максимальная длина для заданных полей.Стиль указателя позволяет выделить правильный объем памяти.Недостатком, как вы упомянули, является гораздо более высокая когнитивная нагрузка на управление вашей структурой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...