Объявить структуру с нулевыми значениями вместо случайной памяти? - PullRequest
0 голосов
/ 24 сентября 2010

У меня есть такая структура:

typedef struct string {
 unsigned long length;
 unsigned *data;
} string;

Могу ли я написать что-нибудь, чтобы, когда я делаю это:

string s;

свойство length равно нулю вместо того, что происходит в памяти? data работает хорошо, так как он установлен на ноль или нулевой указатель.

Пример того, что происходит сейчас:

string s;
printf("length:  %lu\n", s.length);
printf("pointer: %lu\n", (unsigned long) s.data);

Результат:

length:  140737488347584
pointer: 0

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

Дополнительная информация

Теперь, когда я думаю об этом, в моем конкретном случае, возможно, нет необходимости делать это (хотя это было бы неплохо), потому что большинство людей первоначально установили бы строку через ctou (которая импортирует UTF-8 из char указатель) и эта функция в любом случае устанавливает length на ноль.

Ответы [ 4 ]

4 голосов
/ 24 сентября 2010

Вы можете использовать

string s = {0,NULL};
1 голос
/ 25 сентября 2010

Принятый ответ ответил на вопрос, который вы задали, но не указали, должны ли вы.

Ваша строка является классом и имеет семантику класса. Инициализатор может подойти для кода ядра, где учитывается каждая последняя инструкция, но в коде приложения ваши статические инициализаторы уродливы и подвержены ошибкам.

Можно писать классы на C, тип stdio FILE - великолепный пример, и вот та же идея, примененная к вашему строковому классу:

typedef struct {
  int length;
  char *data;
} String;

String *sopen() {
  String *s = malloc(sizeof(String));
  if(s) {
    s->length = 0;
    s->data = NULL;
  }
  return s;
}

int sclose(String *s) {
  free(s->data);
  free(s);
  return 0;
}

int main()
{
   String *s = sopen();
   return sclose(s);
}

Где я следовал стилю имени функции FILE* по метафорическим причинам. Да, есть больше кода. Да, вы должны явно освободить структуру; но учтите, что даже если вы рассчитывали на инициализацию класса auto в своем примере кода, если data был когда-либо выделен, вы не можете рассчитывать на выход из области действия для автоматического освобождения хранилища для вас.

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

1 голос
/ 24 сентября 2010

Чтобы объединить два предыдущих ответа (вроде), я бы определил что-то вроде

#define STRING_INITIALIZER {0, NULL}
.
.
string s = STRING_INITIALIZER;

Кстати, ваше объявление struct выглядит странно для строки .Либо это не строка, как мы обычно понимаем это в C, а просто динамический массив unsigned, или это действительно строка, и тогда это должно быть char*.

0 голосов
/ 24 сентября 2010
#define DEFINE_STRING(s) string s = {0, NULL}

{
    DEFINE_STRING(s);
}

Вы можете использовать макрос, чтобы «сделать это автоматически»

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