1

My question is, I have an C project that has .c files:

trab.c
ordena.c
persistencia.c

persistencia.c Is where I need to read X integer numbers from a .txt file

trab.c has the main. Where I must call persistencia.c to get an array of X (defined by a param in the main) integers and call sorting functions from ordena.c passing said array as param.

My question is. What is the less comples way to do it? Can I declare a global array instead of passing someway through params? Can I use malloc to acess a var from another class?

2
  • Why declare a global array? When you pass an array to a function it degrades to a pointer... which makes it super simple. For an int array you can try void func(int * array, size_t length)... than, just edit the array in place. Commented Sep 16, 2016 at 2:41
  • C does not have 'class's Commented Sep 17, 2016 at 5:17

2 Answers 2

3

You can use malloc to allocate an array of X ints (I'm assuming you know and have #defined X in advance).

int *array = malloc( X * sizeof(int) );

malloc returns a pointer (a variable storing the address in memory) to the array. If X is not known apriori, you could read through the file to determine how many ints there are and add another int* argument to commnicate to the caller how many were read. You can return ptr from the function in persistencia.c as long as it is clear that it is the caller's responsibility to free the memory. The function declaration will look like

int *readInts();

To pass the array to the function in ordena.c you would give it as an argument of type int*

void ordena(int *array, size_t length);
Sign up to request clarification or add additional context in comments.

4 Comments

Two caveats: 1. it is uncommon for functions to return dynamically allocated memory, as it promotes memory leaks (due to mixed concerns regarding memory management); 2. What about the information about the number of elements? How does that fit into readInts?
Thanks, I'll update the answer to note these caveats.
@Myst: I don't think it is unusual for a function to return a pointer to allocated memory in general. Clearly, whenever memory is allocated via malloc() et al, there is a risk that it will be leaked, but that can happen even when it is not returned. The design of the function and the documentation on how to use it should make that clear. Similar comments apply to passing pre-allocated memory into a function. A recursive function adds some twists — especially if the interface can't be changed. That pretty much necessitates some form of global variable.
@JonathanLeffler, I'm not sure we're disagreeing. I wrote at least one function that allocated memory (and the documentation was clear about this)... but I do notice that most designs, especially in libraries but also in long-term maintained projects, avoid returning memory allocated with malloc (months after writing stuff, I rarely remember what I did). From my experience, passing a pointer to user allocated memory (which allows allocation on the stack as well as malloc) is the more common way (and probably the more flexible way) to go.
0

Logan Rakai has a good answer, however, I wish to offer a different approach since my experience shows that it's better not to return dynamic allocated memory when possible (and sometimes it isn't).

A more flexible design would be to write a function that accepts a pointer and the array's size.

Also, when writing long term projects that need to be maintained (probably not just by yourself, but by other programs as well), it's good to keep "concerns" together.

A good example is that when the memory management (free) is performed by the calling function, it is better if the memory allocation (malloc) is performed in the same calling function... When splitting the memory management concern between different functions, it's more likely that future maintainers will introduce memory leaks into the code.

In this case, it's quite simple to allocate an Array using the stack or malloc and pass it along.

i.e., here's a quick (somewhat useless) example for moving the memory management concern into the calling function (main). Notice that this allows you to use both dynamic memory allocation and stack allocation when calling the array related functions.

size_t get_array_size(void /* or any parameters */) {
  /* do whatever you need */
  return 10; /*for our example */
}

void fill_array(int *arry, size_t size) {
  while (size) {
    size--;
    arry[size] = 1; /* fill in data here */
  }
}

int use_array(int *arry, size_t size) {
  fprintf(stderr, "***\n");
  while (size) {
    size--;
    arry[size] -= 1; /* do whatever */
    fprintf(stderr, "array[%lu] == %d\n", size, arry[size]);
  }
  return 0; /* or return -1 for error */
}

int main(int argc, char const *argv[]) {
  int array1[20];
  int *array2;
  size_t array2_size = get_array_size();
  array2 = malloc(sizeof(*array2) * array2_size);
  fill_array(array1, 20);
  fill_array(array2, array2_size);
  if (use_array(array1, 20))
    perror("WTF?! "), exit(0);
  if (use_array(array2, array2_size))
    perror("WTF?! "), exit(0);
  return 0;
}

That's my 2¢. It's possible that my error management code is somewhat perverse, but returning -1 on errors is more common that one would believe.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.