Как установить указатель на struct равным NULL в C?

#c #null

#c #null

Вопрос:

У меня есть массив указателей на struct, и по каким-либо причинам, когда я печатаю этот массив, в его конце есть запасной элемент, и, таким образом, код выводит нулевой байт в конце.

Могу ли я в любом случае удалить последний фрагмент памяти?

Например:

 typedef struct
{
    char *name;
} B;

typedef struct
{
    B *var;
} A;

int main() {
    int num = 5; //for example
    A *foo = malloc(sizeof(A));
    B *bar = malloc(num * sizeof(B));
    for (int i = 0; i < num; i  ) {
        bar[i] = *create_b(amp;bar[i]); // some function that works.
    }
    foo->var = bar;
    while (foo->var != NULL) {
        printf("This is %sn",foo->var->name);
            foo->var  ; 
    }
}
  

Все распечатывается просто отлично, но в конце цикла появляется нежелательная печать. Что-то вроде:

 This is A
This is B
This is C
This is D
This is F
This is
  

По-видимому, в массиве всего 5 элементов, последний ничего не печатает.

Комментарии:

1. Проверьте, является ли массив завершенным null или нет, если он является массивом символов в качестве члена struct . Он не должен его печатать. Это трудно понять, если вы не покажете нам код, который вы на самом деле пытаетесь.

2. вы инициализировали данные в массиве?

3. Можете ли вы показать нам пример рассматриваемого кода? Например, как вы определяете массив, структуру и как вы печатаете массив?

4. Вы уверены, что перебираете right amount элементы, которые есть в массиве указателей?

5. Я только что добавил код 🙂

Ответ №1:

Ваш цикл печати:

 foo->var = bar;
while (foo->var != NULL) {
    printf("This is %sn",foo->var->name);
    foo->var  ; 
}
  

Но foo->var никогда не будет равно NULL, поскольку вы просто увеличиваете указатель, поэтому в конечном итоге вы будете читать дальше конца bar массива, и ваше приложение, вероятно, завершится сбоем.

Если вы замените while цикл на for (int i = 0; i < num; i ) , он выведет правильное количество элементов.

Ответ №2:

Вы не можете этого сделать foo->var , потому что в массиве нет места, для которого установлено значение NULL . Кроме того, использование этого изменения foo->var после того, как цикл foo->var больше не указывает на начало массива, и вы не можете снова получить доступ к массиву.

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

Попробуйте следующее:

 int main() {
    int num = 5; //for example
    A *foo = malloc(sizeof(A));
    B *bar = malloc((num   1) * sizeof(B));  //  1 for array terminator
    for (int i = 0; i < num; i  ) {
        bar[i] = *create_b(amp;bar[i]); // some function that works.
    }
    bar[i].name = NULL;  // Use this as a marker to mean end of array
    foo->var = bar;
    for (B *tmp = foo->var; tmp->name != NULL; tmp  ) {
        printf("This is %sn",tmp->name);
    }
}
  

В коде Edit были некоторые ошибки.

Ответ №3:

Ваша проблема, вероятно, в функции create_b, которую вы не опубликовали.

Редактировать: нет, это, вероятно, неправильно, извините.

Но, конечно, это не то, что вы хотите:

 bar[i] = *create_b(amp;bar[i]);
  

Вы оба передаете адрес bar[i] и устанавливаете его равным тому, на что указывает возвращаемое значение?

Комментарии:

1. Он задает только имя для ‘bar’, которое выводится ok, как вы видите. Но цикл переходит только от 0 к num?