#c #arrays #struct
Вопрос:
Я пытаюсь изменить размер массива, чтобы он содержал значения длиной «newlen». Если значение newlen меньше исходной длины массива, конец массива отбрасывается. Если newlen больше, то новые целые числа должны быть равны нулю. Я придумал эту функцию, но когда я ее тестирую, я получаю ошибку сегментации. Я также не знаю, как добавить нули в конец, как я могу отслеживать индекс, чтобы я мог добавлять нули в конце? Я сделал первый случай (где ньюлен меньше, чем лен), но не знаю, как поступить в другом случае.
Вот структура массива:
typedef struct {
int* data;
unsigned int len;
} intarr_t;
Моя функция:
array_size( intarr_t* p, unsigned int newlength )
{
int i,m = 0;
if (newlength < len)
int *tmp;
tmp = realloc(p->data, (p->newlen)* sizeof *p->data);
if(tmp)
{
for (i; newlength < p->len; i )
{ for (m; newlength < p->len; m )
{
p->data[i] = p->data[m];
}
}
}
}
Комментарии:
1. этот код является одной большой ошибкой,
i
не инициализирован,len
является неизвестной переменной,tmp
не используется,newlen
не используется,double infinite for
… Этот код вообще не должен компилироваться2. Убедитесь
newlength
, что это не1
так . а еще лучше убедитесь, что это сила двух3. Этот код не компилируется. Прежде чем пытаться устранить ошибки во время выполнения, такие как ошибки сегментации: включите ошибки и предупреждения компилятора, исправьте все, о чем сообщалось, и обязательно опубликуйте свой точный код.
Ответ №1:
Указатель, указанный в realloc()
( p->data
), не изменяется.
Использование realloc() обычно должно быть примерно таким
tmp = realloc(old_pointer, new_number * sizeof(*tmp));
if (tmp == NULL)
{
/* an error occur and old_pointer remains unchanged */
/* need to recover */
}
else
{
old_pointer = tmp;
length = new_number;
}
Я предполагаю tmp
, что и old_pointer
они того же типа, что и выше.
Затем вы можете инициализировать дополнительные элементы old_pointer
(при условии, что размер массива увеличивается).
Ответ №2:
Поскольку вы нигде не инициализируете i, прежде чем использовать его в цикле, возможно, это из-за этого.
Также для кода
for (m; newlength < p->len; m )
где вы повторно инициализируете это значение для второго и других проходов цикла for.Кроме того, оба цикла являются бесконечными циклами.
Для реализации второго случая вы можете сделать что-то вроде этого
if(newlength > p->len)
{
int old_length = p->len;
p = realloc(p->data, newlength * sizeof(p->data));
if(p)
memset(p old_length,0,(newlength - old_length) * sizeof(p->data));
}
Вся ваша рабочая функция будет такой
array_size( intarr_t* p, unsigned int newlength ) {
intarr_t * tmp;
if(newlength < p->len) {
tmp = realloc(p->data, newlength * sizeof(p->data)); //realloc will automatically discard elements after new length
if(tmp) {
p = tmp;
p->len = newlength;
}
}
else if(newlength > p->len)
{
int old_length = p->len;
tmp = realloc(p->data, newlength * sizeof(p->data));
if(tmp){
p = tmp;
p->len = newlength;
memset(p old_length,0,(newlength - old_length) * sizeof(p->data));//for setting trailing element to 0
}
}
}
Комментарии:
1. Здравствуйте, извините за мою неполную функцию, я забыл поместить основной файл. Я протестировал этот код, он не изменяет размер массива в нужном диапазоне. Может быть, потому, что он не добавляет элементы для первого случая?
2. В чем разница между размером, который вы получаете
3. Хм, я думаю, это потому, что вы не рассматриваете случай, когда len равен 0. Разница равна 1.