как перераспределить массив double внутри структуры - PullRequest
0 голосов
/ 09 января 2019

Я хотел бы динамически изменить размер массива внутри структуры. Я получил следующую структуру:

struct PolynomStruct {
  double * term;
  unsigned int size;
};

typedef struct PolynomStruct *Polynom;

Когда я пытаюсь создать новый Polynom, я должен зарезервировать память для структуры, чтобы использовать переменные внутри структуры, верно?:

Polynom res = malloc(sizeof(struct PolynomStruct));
res->size = 10;

После этого я хочу добавить двойное значение в массив терминов с индексом 4. Так оно и будет выглядеть [0,0,0,0,2.0000]. Первое, что я делаю, это перераспределяю память массива.

  res->term = realloc(5 * sizeof(double));

По моему мнению размер (res-> term) должен быть 5 * 8 байт = 40 байт. Но следующий код возвращает 8.

printf("size term: %lu\n",sizeof(res->term));

"размер термин: 8"

Впоследствии я попытался сделать это:

res->term[4] = 2;
printf("%f\n",res->term[4] );

Он выводит «2.000000» на стандартный вывод. Я действительно не понимаю, как это работает. Я был бы очень рад, если бы кто-нибудь дал мне подсказку. Извините за мой английский.

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Сначала вы не хотите этого:

Polynom res = malloc(sizeof(struct PolynomStruct));
res->size = 10;

Вы выделили пространство для структуры, но не инициализировали нужный указатель term:

Polynom res = malloc(sizeof(struct PolynomStruct));
if(res==NULL){
  //Handle allocation failure...
}
res_>term=NULL;
res->size = 0;

//Later....
free(res->term);
free(res);

Это выделяет пространство для struct и инициализирует массив как пустой. Обратите внимание, что нормально передавать NULL в free(), он ничего не делает и возвращает нормально.

Или, если вы хотите предварительно выделить 10 терминов:

Polynom res = malloc(sizeof(struct PolynomStruct));
if(res==NULL){
  //Handle allocation failure...
}
res->size = 10;
res_>term=malloc(res->size*sizeof(double));
if(res->term==NULL){
  res->size=0;
  //Handle error...
}

//Later (when finished with res)...
free(res->term);
free(res);

Это предварительно распределяет массив до 10. Если вы предварительно распределили, вы можете отслеживать capac (сколько выделено) и size (сколько используется). Но это выходит за рамки здесь.

Чтобы перераспределить, напишите такую ​​функцию:

int reallocate(Polynom res,int newsize){
    double *resized=realloc(res->term,newsize*sizeof(double));
    if (resize==NULL){
      //Allocation failed. The array is the same size as before.
      return 1; //Or handle error your own way.
    }
    res->term=resized;
    res->size=newsize;
    //realloc may extend the space allocated in place or realloc space elsewhere.
    //If it does reallocate elsewhere the current contents are just copied over 
    //(byte for byte) and the old space freed. 
    return 0;//Success. No error.
}


//Later (when finished with res)...
free(res->term);
free(res);

Часто бывает разумно res=NULL;, чтобы избежать путаницы.

Обратите внимание: если указатель был возвращен malloc или realloc (а не NULL), он должен перейти к free() (ровно один раз).

Также обратите внимание, realloc может уменьшить размер, так что newsize < res->size в порядке.

0 голосов
/ 09 января 2019

Я чувствую, что может быть некоторая путаница с указателем против массива. Пожалуйста, прочитайте эту полезную статью: Эквивалентны ли указатели и массивы в C?

Вы не «изменяете размер массива внутри структуры», потому что весь смысл наличия структуры заключается в поддержании стабильности. Следовательно, Polynom res = malloc (sizeof (struct PolynomStruct)) всегда будет выделять одинаковое количество памятки в куче для res.

Если вы хотите построить массив кучи двойных и точечных терминов, вы можете сделать:

int member=10; // grow array size by member=member*2 for example
double a[]=malloc(member*sizeof(double));
term=a; 

Таким образом, вы можете динамически увеличивать массив.

0 голосов
/ 09 января 2019

sizeof(res->term) возвращает размер указателя, а не выделенной памяти. Вам необходимо вручную отследить выделенную сумму, то есть по res-> size * sizeof (* term) или что-то подобное.

...