LINUX.ORG.RU

Изменение размера массива по указателю

 , , ,


0

2

Необходимо динамически изменять размер массива, помогите исправить код, ошибка скорее всего в неправильном обращении к realloc, пишет на несовместимый тип первого аргумента realloc.

struct str
{
	 int **a;
};

void changeSize (struct str * ps);

int main()
{
        struct str s;
        s.a = (int*)malloc(1);
        changeSize (&s);
        return 0;
}

void changeSize (struct str * ps)
{
        ps->a=(int*)realloc(ps->a, 2);
}



Последнее исправление: vodozheg (всего исправлений: 2)

Вот что в примере сppreference

int main ()
{
  int input,n;
  int count = 0;
  int* numbers = NULL;
  int* more_numbers = NULL;

  do {
     printf ("Enter an integer value (0 to end): ");
     scanf ("%d", &input);
     count++;

     more_numbers = (int*) realloc (numbers, count * sizeof(int));

     if (more_numbers!=NULL) {
       numbers=more_numbers;
       numbers[count-1]=input;
     }
     else {
       free (numbers);
       puts ("Error (re)allocating memory");
       exit (1);
     }
  } while (input!=0);

  printf ("Numbers entered: ");
  for (n=0;n<count;n++) printf ("%d ",numbers[n]);
  free (numbers);

  return 0;
}
В использование есть различия

Silerus ★★★★
()

*-чки не хватало в 11-ой и 18-ой строках, но это предупреждения, не ошибки.

#include <stdlib.h>

struct str
{
         int **a;
};

void changeSize (struct str * ps);

int main()
{
        struct str s;
        s.a = (int**)malloc(1);
        changeSize (&s);
        return 0;
}

void changeSize (struct str * ps)
{
        ps->a=(int**)realloc(ps->a, 2);
}

backbone ★★★★★
()
Ответ на: комментарий от Silerus

И к чему этот пример? что делает и зачем нужен realloc я и так знаю (ну или думаю что знаю, если видите что я не прав укажите явно).

vodozheg
() автор топика
Ответ на: комментарий от backbone

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

vodozheg
() автор топика
Ответ на: комментарий от vodozheg

вы гляньте на размер выделенной памяти для массива, она не меняется (ну или я меряю непонятным образом )

а с чего ей меняться ? во первый непонятно что ВЫ измеряете. Размер структуры останется как был при компиляции.. Размер блока памяти выделенного по указателю под «массив», тоже вряд-ли изменится, но это зависит от аллокатора.

вы реаллоцируете 1 байт в 2...на 99.99% просто поменяется одно число в структурах аллокатора, при этом никаких переносов данных и изменений объёмов не будет

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 1)
Ответ на: комментарий от MKuznetsov

всё я понял, действительно в C нельзя глянуть размер массива, а я смотрел на размер выделяемого блока. тогда вопрос отпал сам собой, код отрабатывает как надо, это я уже туплю

vodozheg
() автор топика
Ответ на: комментарий от vodozheg

действительно в C нельзя глянуть размер массива

valgrind'ом смотри

anonymous
()
Ответ на: комментарий от vodozheg

Память алоцированная малоком или реалоком это НЕ массив, а узнать размер МАССИВА в С можно.

Jetty ★★★★★
()

Да у тебя тут куча ошибок. Во-первых, ты не понимаешь указатели и путаешь int* и int**. Массив интов это первое. Второе - это массив массивов, и для него нужно также выделять каждый вложенный массив. Во-вторых, ты не понимаешь как работает malloc либо вообще как устроена память. И выделяешь 1 и 2 байта под то-ли массив интов, то-ли массив указателей, при том что ни инт, ни указатель в 1 или 2 байта обычно не влезут. В-третьих, ты не проверяешь возвращаемое значение от malloc и realloc. foo = realloc(foo) это вообще известный антипаттерн, поскольку если realloc провалится, ты получишь не только NULL, но и утечку памяти.

slovazap ★★★★★
()
Ответ на: комментарий от anonymous

Вот когда я в каком то вопросе нуб и вместо внятного ответа меня посылают читать книжку на 1000 страниц это бесит. И наверное не только меня. Мне надо решение сейчас а не тратить пару месяцев на чтение макулатуры.
К слову на SO люди куда терпеливее и культурнее.

bga_ ★★★★
()
Ответ на: комментарий от slovazap

Сейчас вроде malloc/realloc не валится в принципе. Тк все выделяется лениво по CoW и в виртуальном пространстве. На x86 еще можно словить фейл выделения памяти тк виртуального пространства всего 4ГБ но на x64 уже наверное невозможно.

bga_ ★★★★
()
Ответ на: комментарий от bga_

Не, человек кидает код, который полностью состоит из ошибок и непонимания языка, платформы и вообще много чего. Если б ответ можно было бы уместить в пару строк, то я уверен, что ответ бы он получил. Тут же ему как минимум надо прочитать пору лекций по основам. Это тянет или на оплачиваемую работу, ну или на совет где можно эти знания найти.

Dudraug ★★★★★
()
Ответ на: комментарий от bga_

Ну не знаю. У меня вот это:

#include <stdlib.h>
#include <stdio.h>
int main(void) {
  printf("%p\n", malloc(1024ull*1024*1024*1024));
}
печатает (nil).

Насколько мне известно, настройки аллокаторов я не менял.

i-rinat ★★★★★
()

Как правильно

struct str
{
	 int *a;
};

void changeSize (struct str * ps);

int main()
{
        struct str s;
        s.a = (int*)malloc(1 * sizeof(int));
        changeSize (&s);
        return 0;
}

void changeSize (struct str * ps)
{
        ps->a=(int*)realloc(ps->a, 2 * sizeof(int));
}
У тебя ошибка на 2ой строчке.
И malloc/realloc выделяет байты а не элементы массива. Потому надо везде дописывать * sizeof(типЭлемента)

bga_ ★★★★
()
Ответ на: комментарий от i-rinat

x64? Ну терабайт это многовато. Лучше выдели что то более приземленное но не пиши туда. И посмотри реальное потребление памяти. Должно быть так: пока не пишешь - реально страницы не выделяются.

bga_ ★★★★
()
Ответ на: комментарий от bga_

Много не много, но NULL из malloc вполне реально получить. А если лимит поставить на виртуальную память процесса, то можно словить NULL и на мелких аллокациях. Поэтому нужно этот NULL обрабатывать. Хотя бы abort'ом.

i-rinat ★★★★★
()
Ответ на: комментарий от bga_

Вот когда будет не «вроде» и «наверное», а гарантированно на всех системах, платформах, гипервизорах и окружениях, тогда будете такие заявления делать. А пока почитайте хотя бы про setrlimit(RLIMIT_AS) или ulimit -v, я даже не говорю про адресное пространство amd64.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от bga_

это типа стёб такой? k&r от силы 300 страниц, учитывая код и приложения в конце книги. там чистой теории хорошо если на сотню страниц нашкребетётся

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.