2015-03-22 2 views
0

Вот мои два: СтруктурыКак проверить, нет ли структуры внутри другой структуры?

typedef struct simple_command_t { 
    char * in, *out, *err; 
    char **tokens; 
    int builtin; 
} simple_command; 

typedef struct command_t { 
    struct command_t *cmd1, *cmd2; 
    simple_command* scmd; 
    char oper[2]; 
} command; 

А вот код я использую:

int main() { 
    command *check1; 

    if ((check1 -> scmd -> tokens) == NULL){ 
     printf("tokens are null"); 
    } 

    return 0; 
} 

Поскольку я читал, что вы не можете проверить, если структура является NULL я ve попытался проверить членов внутри пустой структуры. К сожалению, все, что я пробовал до сих пор, дало мне некоторые недостатки. В чем проблема?

+0

Помните, что автоматические (= локальные) переменные не инициализируются. Вы должны явно указать их члены null. Это означает, что вы не можете знать, является ли '(check1 -> scmd -> токены) == NULL)' true или нет. В коде, который вы видите, 'scmd' не будет инициализирован ничем, поэтому ваша программа либо производит бессмысленность (на небольших системах), либо рушится вправо (на современных нормальных компьютерах). Один простой способ обнулить ваши переменные (включая структуры) - это определить их с внешней связью (вне любой функции) или статикой (внутри функции). –

+0

Какова общая цель, которую вы пытаетесь достичь? – reuben

+0

Как проверить, не выполнил ли кто-то его тогда? Этот код предполагает, что кто-то инициализировал check1 и инициализировал все остальное, но ничего не установил scmd. Поэтому мне нужно выяснить, не вызвал ли пользователь scmd. – user125535

ответ

4

Нет такой вещи, как «пустая» структура. (Фраза «пустая структура» имеет смысл, если C разрешает структуры без членов, но это не так, и это не то, о чем вы говорите.)

Я думаю, что вы пытаетесь сделать это проверьте, была ли структура инициализирована либо с помощью инициализатора, либо с присвоением. Это невозможно.

Вот простой пример:

#include <stdio.h> 
#include <stdlib.h> 
int main(void) { 
    int *ptr; 
    /* code that may or may not initialize ptr */ 
    if (<ptr has been initialized>) { 
     printf("ptr = %p, *ptr = %d\n", (void*)ptr, *ptr); 
    } 
    else { 
     fprintf(stderr, "ptr is uninitialized\n"); 
     exit(EXIT_FAILURE); 
    } 
} 

Там нет никакого способа записать условие <ptr has been initialized>. Поскольку ptr не является объектом static, его начальное значение необязательно является нулевым указателем или любым другим конкретным значением; это неопределенный мусор. Он мог бы, просто по совпадению, содержать действительный адрес; нет возможности различать эту возможность и фактическое действительное значение, которое было запомнено в ptr.

Единственный надежный способ определить, является ли ptr инициализирован или нет инициализировать его:

int *ptr = NULL; 

То же рассуждение относится и к вашему примеру. Вы определяете объект указателя:

command *check1; 

Это определено в стороне функцию, это не static, поэтому его начальное значение является неопределенным мусора. Просто прочитав значение указателя:

if (check1 == NULL) ... 

имеет неопределенное поведение; даже если бы этого не произошло, результат сравнения не сказал бы вам ничего полезного. Вы должны тщательно написать свой код, чтобы вы никогда не пытались использовать значение check1, прежде чем назначать ему известное значение. Самый простой способ сделать это, просто инициализировать его:

command *check1 = NULL; 

Если вы инициализировать его NULL не указывает ни на что; нет объекта структуры для тестирования. Вы можете создать структуру и назначить его адрес check1:

check1 = malloc(sizeof *check1); 

Теперь check1 имеет действительное значение (которое еще может быть пустой указатель malloc неуспешно; всегда проверяйте, что). Если malloc удалось, check1 указывает на объект struct, значение которого является неопределенным мусором. Те же соображения, которые применяются к check1, теперь применяются к объекту struct *check1 и к каждому из его членов.

Один общий подход - определить функцию, которая создает объект struct и правильно инициализирует все ее элементы.

Смежные вопросы