简体   繁体   中英

Allocating space for an array of structs, and learning some C

Trying to learn some C here.

Generically I am trying to implement those situations using dynamic allocation.

  • a pointer to an array of dates pointers
  • a pointer to an array of dates
  • an array of dates pointers
  • an array of dates

Could you please help me in building those structures / checking if my thoughts are OK?

#include <stdio.h>
#include <stdlib.h>
#define SIZE 2

typedef struct date {
  int year;
  short month;
  short day;
  char* wday;
} Date;

typedef struct date DatesArr[SIZE];
typedef struct date* DatesPtr;

void printDate(Date d){ printf("%d-%d-%d %s\n", d.year, d.month, d.day, d.wday); }

void printDatePtr(Date* d){ printf("%d-%d-%d %s\n", d->year, d->month, d->day, d->wday); }

int main(int argc, char *argv[]){
  Date a = *(Date*)malloc(sizeof(Date));
  a.year = 2016; a.month = 6; a.day = 12; a.wday = "sunday";
  Date b = *(Date*)malloc(sizeof(Date));
  b.year = 2016; b.month = 6; b.day = 13; b.wday = "monday";

  //Date* y = &a;  // reuse previous
  Date* y = (Date*)malloc(sizeof(Date));
  y->year = 2016; y->month = 4; y->day = 25; y->wday = "monday";
  Date* z = (Date*)malloc(sizeof(Date));
  z->year = 2016; z->month = 3; z->day = 27; z->wday = "sunday";

  // a pointer to an array of dates pointers !OK
  DatesPtr* yz = (DatesPtr *)malloc(sizeof(Date*)*SIZE);
  yz[0] = y; yz[1] = z;
  for(int i=0;i<SIZE;i++){ printDatePtr( yz[i] ); }

  // a pointer to an array of dates !OK
  DatesPtr* ab = (DatesPtr *)malloc(sizeof(Date)*SIZE);
  ab[0] = &a; ab[1] = &b;
  for(int i=0;i<SIZE;i++){ printDate( *ab[i] ); }

  // an array of dates pointers // error
  DatesArr zy[] = *(DatesArr *)malloc(sizeof(Date*)*SIZE);
  zy[0] = y; zy[1] = z;
  for(int i=0;i<SIZE;i++){ printDatePtr( zy[i] ); }

  // an array of dates // error
  DatesArr ba = *(DatesArr *)malloc(sizeof(Date)*SIZE);
  ba[0] = a; ba[1] = b;
  for(int i=0;i<SIZE;i++){ printDate( ba[i] ); }

  //free(a); // error: free only accepts a pointer to a Date
  free(y);  // runs ok
  return 0;
}

Let us examine one: an array of dates.

Code needs a type of a pointer Date * , not of Date .

// bad
Date a = *(Date*)malloc(sizeof(Date));
// better
Date *a = (Date*)malloc(sizeof(Date));
// better yet - cast not needed in C
Date *a = malloc(sizeof(Date));
// better yet: allocate per the sizeof of the de-referenced type.
Date *a = malloc(sizeof *a);
// As needed, code needs 4 for a,b,y,z
Date *a = malloc(sizeof *a * 4);

Example

int main(void) {
  //                   size of element   how many 
  Date *dates = malloc(sizeof *dates   *   4);
  //Check for success
  if (dates) {
    // C11 use of compound literal  
    dates[0] = (Date){ 2016, 6, 12, "sunday"};  // a
    dates[1] = (Date){ 2016, 6, 13, "monday"};  // b
    dates[2] = (Date){ 2016, 4, 25, "monday"};  // y
    dates[3] = (Date){ 2016, 3, 27, "sunday"};  // z
    // do stuff with dates[]
  }
  // free when done, OK to free(NULL)
  free(dates)
  return 0;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM