#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?