There is a code:

… //Функция, которая запрашивает указатель на одномерный массив void AbstractName(int* row_size){ int rows;scanf_s("%d",rows); row_size = (int*)malloc(sizeof(int)*rows); for (int i = 0; i < *rows; i++) scanf_s("%d",&row_size[i]); } … ///Где-нибудь в основной части: //Объявление указателя на одномерный массив и его инициализация "нулём" int* row_size = (int*)malloc(0); AbstractName(row_size); … 

So: after executing the "AbstractName" function in the main part of the program, row_size still stores the address of the section of memory that was used to initialize it (ie, "0").

Question: how to pass into the function the array pointer so that after it executes the function code it can work with it?

  • one
    void AbstractName(int** row_size){ ... *row_size = (int*)malloc(sizeof(int)*rows); ...} void AbstractName(int** row_size){ ... *row_size = (int*)malloc(sizeof(int)*rows); ...} and call ...AbstractName(&row_size);... - avp
  • Thank you, I will try to understand the question thanks to your answer. - Sergey NaN
  • @SergeyNaN for (int i = 0; i <* rows; i ++) - Why is there an asterisk in front of the rows ?! - Sergey
  • @avp, you can simply follow the index, why should you fuss from a double garden? - 0andriy 8:19 pm
  • You would understand what malloc(0) means ... - 0andriy

1 answer 1

Firstly, if you have already assigned the address of the dynamically allocated memory to the source pointer, then in the function you should use the function realloc instead of malloc . Otherwise, you will have a memory leak.

To change a source pointer in a function, it must be passed by reference, that is, through a pointer to a pointer.

Below is a demonstration program.

 #include <stdio.h> #include <stdlib.h> void f( int **p, size_t n ) { int *tmp = realloc( *p, n * sizeof( *tmp ) ); if ( !tmp ) { free( *p ); } else { for ( size_t i = 0; i < n; i++ ) tmp[i] = ( int )i; } *p = tmp; } int main(void) { size_t n = 5; int *a = malloc( n * sizeof( int ) ); for ( size_t i = 0; i < n; i++ ) a[i] = ( int )i; for ( size_t i = 0; i < n; i++ ) { printf( "%d ", a[i] ); } putchar( '\n' ); n *= 2; f( &a, n ); for ( size_t i = 0; i < n; i++ ) { printf( "%d ", a[i] ); } putchar( '\n' ); free( a ); return 0; } 

Its output to the console:

 0 1 2 3 4 0 1 2 3 4 5 6 7 8 9 

In general, after exiting a function, you should check that the NULL pointer is not equal to avoid undefined behavior.

If you do not want to free up memory for an already allocated array in case of a memory redistribution within a function, then you can return a logical value from the function, indicating success or failure of memory allocation.

For example,

 _Bool f( int **p, size_t n ) { int *tmp = realloc( *p, n * sizeof( *tmp ) ); _Bool success = tmp != NULL; if ( success ) { for ( size_t i = 0; i < n; i++ ) tmp[i] = ( int )i; *p = tmp; } return success; } 

And there is no need to initialize the pointer as follows:

 int* row_size = (int*)malloc(0); 

It is enough to write initially

 int* row_size = NULL;