简体   繁体   中英

Passing pointer of pointers to function, returning both an int and an address (by parameter)

I've got a function which, as is, works correctly. However the rest of the program has a limitation in that I've preset the size of the array (the space to be allocated). Obviously, this is problematic should an event arise in which I need extra space for that array. So I want to add dynamic allocation of memory into my program.

But I'm having an issue with the whole pointer to a pointer concept, and I've utterly failed to find an online explanation that makes sense to me... I think I'll want to use malloc(iRead + 1) to get an array of the right size, but I'm not sure what that should be assigned to... *array? **array? I'm not at all sure.

And I'm also not clear on my while loops. &array[iRead] will no longer work, and I'm not sure how to get a hold of the elements in the array when there's a pointer to a pointer involved.

Can anyone point (heh pointer pun) me in the right direction?

I can think of the following approaches.

  1. First approach

    1. Make two passes through the file.
    2. In the first pass, read the numbers and discard them but keep counting the number of items.
    3. Allocate memory once for all the items.
    4. Rewind the file and make a second pass through it. In the second pass, read and store the numbers.

       int getNumberOfItems(FILE* fp, int hexi) { int numItems = 0; int number; char const* format = (hexi == 0) ? "%X" : "%d"; while (fscanf(fp, format, &number) > 0) { ++numItems; return numItems; } void read(int *array, FILE* fp, int numItems, int hexi) { int i = 0; char const* format = (hexi == 0) ? "%X" : "%d"; for ( i = 0; i < numItems; ++i ) fscanf(fp, format, &array[i]); } int main(int argc, char** argv) { int hexi = 0; FILE* fp = fopen(argv[1], "r"); // if ( fp == NULL ) // Add error checking code // Get the number of items in the file. int numItems = getNumberOfItems(fp, hexi); // Allocate memory for the items. int* array = malloc(sizeof(int)*numItems); // Rewind the file before reading the data frewind(fp); // Read the data. read(array, fp, numItems, hexi); // Use the data // ... // ... // Dealloate memory free(array); } 
  2. Second approach.

    1. Keep reading numbers from the file.
    2. Every time you read a number, use realloc to allocate space the additional item.
    3. Store the in the reallocated memory.

       int read(int **array, char* fpin, int hexi) { int number; int iRead = 0; // Local variable for ease of use. int* arr = NULL; char const* format = (hexi == 0) ? "%X" : "%d"; FILE *fp = fopen(fpin, "r"); if (NULL == fp){ printf("File open error!\\n"); exit(-1); } while (fscanf(fp, format, &number) > 0) { arr = realloc(arr, sizeof(int)*(iRead+1)); arr[iRead] = number; iRead += 1; } fclose(fp); // Return the array in the output argument. *array = arr; return iRead; } int main(int argc, char** argv) { int hexi = 0; int* array = NULL; // Read the data. int numItems = read(&array, argv[1], hexi); // Use the data // ... // ... // Dealloate memory free(array); } 

I'd suggest something like this:

int read(int **array_pp, char* fpin, int hexi) {
  ...
  int *array = malloc (sizeof (int) * n);
  for (int i=0; i < n; i++)
    fscanf(fp, "%X",&array[i]);
  ...
  *array_pp = array;
  return n;
}

Notes:

1) You must use "**" if you want to return a pointer in a function argument

2) If you prefer, however, you can declare two pointer variables (array_pp and array) to simplify your code.

int read(int **array, char* fpin, int hexi) {
   int iRead = 0;
   int i, *ary;
   char *para;
   FILE *fp;

   fp = fopen(fpin, "r");
   if (NULL == fp){
      printf("File open error!\n");
      exit(-1);
   }

   para = (hexi == 0) ? "%*X" : "%*d";
   while (fscanf(fp, para)!= EOF)
     ++iRead;

   ary = *array = malloc(iRead*sizeof(int));
   if(ary == NULL){
      printf("malloc error!\n");
      exit(-2);
   }
   rewind(fp);
   para = (hexi == 0) ? "%X" : "%d";
   for(i = 0; i < iRead; ++i)
      fscanf(fp, para, &ary[i]);

   fclose(fp);
   return iRead;
}

I think you wouldn't call it an array. Arrays are of fixed size and lie on the stack. What you need (as you already said), is dynamically allocated memory on the heap.

maybe that's why you didn't find much :) here are some tutorials:

you got the function declaration correctly:

int read(int **array, char* fpin, int hexi)

What you need to do:

  1. find out how much memory you need, eg. how many elements
  2. allocate it with *array = malloc(numElements * sizeof(int)) (read "at the address pointed by array allocate memory for numElements ints")
  3. now you can (*array)[idx] = some int (read "at the address pointed by array, take the element with index idx and assign some int to it")
  4. call it with int* destination; int size = read(&destination, "asdf", hexi) int* destination; int size = read(&destination, "asdf", hexi)

hope it helps..

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