jramm
jramm

Reputation: 6655

C modern array allocation?

I have some code to create a new struct and allocate some space for an array of structs. Initially, I allocate space for 1 struct on the array:

static int datasetCount = 0;

int datasetgroup_new(DatasetGroup *dg char *id){

  dg->id = id;

  // Allocate space for a single dataset to start with
  dg->datasets = (Dataset *) malloc(sizeof(Dataset));

  return 0;

}

I then have a function to add another struct ('dataset') to the struct containing the array. At the end of the function, I reallocate the array to provide another space:

void datasetgroup_add(DatasetGroup *dg, string filePath){

  // Create the dataset
  Dataset ds;
  dataset_new(&ds, filePath);

  // Copy the dataset to the dataset array
  dg->datasets[datasetCount] = ds;

  // Increment the dataset counter
  datasetCount++;

  //Grow the array
  dg->datasets = (Dataset *)realloc(dg->datasets, sizeof(Dataset) * (datasetCount + 1));

}

I keeping reading things that hint that in modern C you don't need to do stuff like this. I may be wrong...so is the a more modern/correct way to do this?

Edit:

Sorry, to be clear that I am not using C++ types, I have created a typedef for string:

typedef char* string;

Upvotes: 4

Views: 330

Answers (2)

Parham Alvani
Parham Alvani

Reputation: 2440

As mentioned here there is nothing for this in modern C (C11) standard but you can use libraries like Glib in order to easier memory management or you can use it's data structures like array.

If you use visual studio may be you could find some non-standard function for this in that.

To be more specified in linux, these functions just wrapper for brk() system call and all of them do memory management in user space and their speed and efficiently depend on their algorithms, for example GNU C Library get some space in heap and then manage it for you so not all of your realloc() call end into brk() system call, so do not worry yourself about their efficiently so much. you can use valgrind in order to see your memory profiling.

Upvotes: 4

Arun
Arun

Reputation: 20383

I am not clear what you mean by modern C, however there are two things in the code that I want to mention.

The usage style of realloc is wrong. In case it fails and returns NULL, then the original memory would be leaked. See, for example, Dynamic arrays: using realloc() without memory leaks

The logic of growing memory invokes realloc and thus memory allocation on every addition (i.e. call to datasetgroup_add). It increases the size/capacity of the dynamic array by one. This may not be ideal. The commonly used idiom for growing such memory is to double it whenever the capacity becomes full. That way, cost of memory allocation is amortized (What is amortized analysis of algorithms?) over all the calls.

Upvotes: 3

Related Questions