Why is the pointer not de-referenced in the function max? - c

// function t find the max value entered in the array
double max(double *n,int size)
{
int i,k=0;
double *maxi;
maxi=&k;
for(i=0;i<size;i++)
{
if(*maxi<n[i])
{
maxi=&n[i];
}
}
return *maxi;
}
//elements of array are added
main()
{
double a[10000],maxi;
int size,i;
printf("enter the size of the array");
scanf("%d",&size);
printf("enter the elements of array");
for(i=0;i<size;i++)
{
scanf("%lf",&a[i]);
}
maxi=max(&a,size);
printf("maximum value is %lf",maxi);
}
Why is the pointer not de-referenced in the function max? If I de-reference the pointer n it gives an error. If there is a better way to do this, please suggest.

n[i] is the very same thing as *(n + i). So the pointer is de-referenced, through the [] syntax.
As for why you are getting an error, it is impossible to tell without you posting the problematic code.

Passing the array/pointer as argument and dereferencing are both wrong.
maxi=max(&a,size); // passing address of the address
if(*maxi<n[i]) // k is compared to memory garbage
maxi=&n[i]; // maxi is assigned with memory garbage
Consider following:
double max( double * na, int size ) // n changed to na
{
int idx; // changed i to idx;
double max; // forget about k and maxi, just simply max
if( 0 < size )
{
max = na[0]; // init max to 1st elem
for( idx = 1; idx < size; ++idx ) // iterate from 2nd elem
{
if( max < na[idx] ) { max = na[idx]; } // check for larger
}
}
return max;
}
int main()
{
double an[10000],maxi; // a changed to an
// ..
maxi = max( an, size ); // pass an not &an
// ..
return 0;
}

Related

multi pointers in function in c

i'm not good at english.
i declare array and two pointers.
the maxPtr pointer should have array arr's maximum number adress.
and minPtr pointer should have array arr's minimum number adress.
so i declare the function and this has two double-pointer to give maxPtr and minPtr proper adress.
but whenever i run this code, the program is not fully run.
it doesn't output the result( printf("%d",*maxPtr) ,printf("%d", *minPtr, printf("Hi");
this program is run at vscode in mac.
what make it error?
#include <stdio.h>
void MaxAndMin(int* str,int** max, int** min)
{
int i;
int maxnum=0,minnum=0;
for(i=0; i<5; i++)
{
if(maxnum< str[i])
{
maxnum =str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
}
int main(void)
{
int i,len;
int* maxPtr;
int* minPtr;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("%d번째 정수입력 입니다.",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr,&maxPtr,&minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}
the result is
> Executing task: ./test <
1번째 정수입력 입니다.1
2번째 정수입력 입니다.2
3번째 정수입력 입니다.3
4번째 정수입력 입니다.4
5번째 정수입력 입니다.5
Terminal will be reused by tasks, press any key to close it.
For starters this initialization of an array
int arr[5]={};
is incorrect in C. You have to write
int arr[5]={ 0 };
Secondly using the magic number 5 within the function makes the function useless in general. You need to pass to the function the size of the array.
The initial value 0
int maxnum=0,minnum=0;
of these variables makes the function even more less useful. In general the array can contain either all elements positive or all elements negative.
And you need to flush the output buffer using for example the new line character '\n' in calls of printf.
The function can be declared and defined the following way as it is shown in the demonstration program below.
#include <stdio.h>
void MaxAndMin( const int a[], size_t n, int **max, int **min )
{
*max = ( int * )a;
*min = ( int * )a;
for ( size_t i = 1; i < n; i++ )
{
if ( **max < a[i] )
{
*max = ( int *)( a + i );
}
else if ( a[i] < **min )
{
*min = ( int * )( a + i );
}
}
}
int main( void )
{
int a[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
const size_t N = sizeof( a ) / sizeof( *a );
int *maxPtr = NULL;
int *minPtr = NULL;
MaxAndMin( a, N, &maxPtr, &minPtr );
printf( "The maximum value is %d at position %tu\n",
*maxPtr, maxPtr - a );
printf( "The minimum value is %d at position %tu\n",
*minPtr, minPtr - a );
}
The program output is
The maximum value is 9 at position 9
The minimum value is 0 at position 0
Pay attention to that the first parameter of the function should have the qualifier const because passed arrays to the function are not changed within the function.
The main issue is that the minnum is set at zero, which would only work if array had a negative value.
Setting minimum = star[0] also would not work!!! Because in the case of str[0] having negative value, *min never gets changed.
Also, I recommend to always initialize all variables in the declaration, especially pointers (because they may theoretically cause accidental access to memory).
Full solution:
#include <stdio.h>
int MaxAndMin(int* str, int** max, int** min)
{
int i;
int maxnum = 0;
int minnum = str[0] + 1;
for(i=0; i<5; i++)
{
if(maxnum < str[i])
{
maxnum = str[i];
*max = &str[i];
}
if(minnum > str[i])
{
minnum = str[i];
*min = &str[i];
}
}
return 0;
}
int main(void)
{
int i = 0;
int len = 0;
int* maxPtr = NULL;
int* minPtr = NULL;
int arr[5]={};
for(i=0; i<5; i++)
{
printf("Enter number %d: ",i+1);
scanf("%d", &arr[i]);
}
MaxAndMin(arr, &maxPtr, &minPtr);
printf("%d",*maxPtr);
printf("%d",*minPtr);
printf("Hi");
return 0;
}

Array Rotation with Getting Max Value and Index Location of Array C language

I'm creating a program that gets the index value of the highest element in an array.
Sample Input:
4 (Size of a[])
1 2 4 3 (Elements of a[])
2 (Size of rotate[])
0 2 (Elemnts of rotate[])
Output will be:
2
0
Using left rotation.
In the First Rotation (0) the location will be 2 because 4 is the highest a[1,2,4,3]
In the Second Rotation (2) the location will be 0 because 4 is the highest a[4,3,1,2]
Problem is i'm not getting the desired output and there was a warning in for(j=0;j<rotateValue;j++)
I want the function to be as it is and to fix this part to int* output = getMaxIndex(a,rotate);
but i don't know how.
Thank you in advance for helping!
#include<stdio.h>
int i,j,k; // for looping
int n, m; // sizes of arrays
int getMaxIndex(int* a[], int* rotate[])
{
int indices[m];
for(i=0;i<m;i++)
{
int* rotateValue = rotate[i];
for(j=0;j<rotateValue;j++) // for rotation
{
int* first = a[0];
for(i=0;i<n-1;i++)
{
a[i] = a[i+1];
}
a[n-1] = first;
}
int location;
int* max = a[0];
for(j=0;j<n;j++) // getting the max element
{
if(a[j] > max)
{
max = a[j];
// printf("Max added");
}
}
for(j=0;j<n;j++) // getting the location
{
if(max == a[j])
{
location = j;
// printf("Loc added");
}
}
indices[i] = location;
}
// for(i=0;i<m;i++) // printing here to know if correct
// {
// printf("%d",indices[i]);
// }
return *indices;
}
int main()
{
scanf("%d",&n); // inputting array size
int* a[n];
for(i=0;i<n;i++) // filling elements of a[]
{
scanf("%d",&a[i]);
}
scanf("%d",&m); // inputting rotate array size
int* rotate[m];
for(i=0;i<m;i++) // filling elements of rotate[]
{
scanf("%d",&rotate[i]);
}
int* output = getMaxIndex(a,rotate); // call function
for(i=0;i<m;i++) // printing output
{
printf("%d",output[i]);
}
}
int getMaxIndex(int* a[], int* rotate[]);
Designing getMaxIndex() in the following way should solve most of the issues:
int* getMaxIndex(int a[], int rotate[])
{
static int indices[MAX_POSSIBLE_VALUE_OF_M];
/*
your code
*/
return indices;
}
Now, all you have to do is adjust your code in the main() function accordingly.
Why declare the array indices[] in getMaxIndex() as static int?
indices[] is a local variable of getMaxIndex(). And so after the return statement of getMaxIndex() is executed, it shall be destroyed. That means, if you return indices[] to main(), the main function will not be able to access indices[] anymore. And this issue can be solved by declaring indices[] as a static int instead of int.
NOTE: static array should have constant size. So, its size should be declared as maximum possible value of m instead of m.
Required adjustments in main():
Declare a[] and rotate[] as int instead of int*.
Check out my code.I am getting the correct output. I have written down a few mistakes that you have made.
void getMaxIndex(); //function declaration
int n, m; //for storing array size
int * a, * rotate;
int main(void) {
int i; //to use in loops
scanf("%d", & n); // inputting array size
a = (int * ) malloc(n * sizeof(int));
for (i = 0; i < n; i++) // filling elements of a[]
{
scanf("%d", & a[i]);
}
scanf("%d", & m); // inputting rotate array size
rotate = (int * ) malloc(m * sizeof(int));
for (i = 0; i < m; i++) // filling elements of rotate[]
{
scanf("%d", & rotate[i]);
}
getMaxIndex();
free(a);
free(rotate);
return 0;
}
void getMaxIndex() {
int i;
int aMax, rotateMax;
int aMaxIndex, rotateMaxIndex;
aMax = a[0];
rotateMax = rotate[0];
for (i = 1; i < n; i++) {
if (aMax < a[i]) {
aMax = a[i];
aMaxIndex = i;
}
}
for (i = 1; i < m; i++) {
if (rotateMax < rotate[i]) {
rotateMax = rotate[i];
rotateMaxIndex = i;
}
}
printf("%d\n%d", aMaxIndex, rotateMaxIndex);
}
My suggestions:
Always try to allocate memory for your array dynamically so that you can avoid errors such as Segmentation Fault or Core Dump.
In your code you have used array of pointers instead of pointers, there you went wrong. Try refering to your textbook or other sources to get a clear idea regarding pointers.
For example, in your code you passed your array named indices using the line:
return indices;
Now, to pass a pointer you don't need to use asterisk(). Simply write: return indices;
Also, don't use asterisk symbol to declare an array.
Your Code:
int* a[n];
Here you are declaring an array of pointers not an array.
Correct code:
int a[n];
But I liked your logic. You just have to implement it with the correct syntax. Just keep practicing.
I the code which I've written is understood by you, my work here is done. Happy Coding!!!

Allocate 2D array

I have a segment fault int this exercice.
Instruction:
• Write an ft_ultimate_range function which allocates and assigns an int array. This int table will contain all values ​​between min and max.
• Min included - max excluded.
• If the min value is greater than or equal to the max value, range will point to NULL.
• The range size will be returned (or 0 in the event of a problem).
#include <stdlib.h>
#include <stdio.h>
int ft_ultimate_range(int **range, int min ,int max)
{
int len;
int i;
i = 0;
len = max - min;
if (min >= max)
{
*range = NULL;
return(0);
}
**range = (int)malloc(sizeof(int) * len);
while (min < max)
{
range[0][i] = min;
i++;
min++;
}
return(len);
}
int main()
{
int min;
int max;
int **range = NULL;
min = 0;
max = 10;
printf("%d\n", ft_ultimate_range(range, min, max));
return(0);
}
**range = (int)malloc(sizeof(int) * len);
This line raises the warning when i compile your code:
warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
Never ignore the warning from the compiler.
malloc function returns a pointer, why do you cast it to int value ?
You want 2D array, but i seems that is matrix 1 x len, it's 1D array (vector).
OK, forget the 2D or 1D array (vector). If you want to use double pointer in your code, you have allocate for it first.
// this line should be in main function
range = malloc(sizeof(int *));
if(!range) {
return -1;
}
// this line before while loop
range[0] = malloc(sizeof(int)*len);
if(!range[0]) {
return -1;
}
If you want a matrix "M*N", you can allocate the pointer as below:
// allocate double pointer
range = malloc(sizeof(int *)*M);
if(!range) {
return -1;
}
// then using a loop to allocate the pointers:
for(int i = 0; i<N; i++) {
range[i] = malloc(sizeof(int)*N);
if(!range[i]) {
return -1;
}
}
Do not forget to free the pointer when you do not need to use (free(range[i] then free(range)).
As you have guessed your allocation is wrong
by writing
**range = (int)malloc(sizeof(int) * len);
you meant to assign to the dereference of the dereference of range (NULL)
range = NULL
*range = whatever value is at offset 0
**range = whatever value is at the address from the value read at address 0
please read this for writing the allocator
it would boil down to:
array = malloc( sizeof(int[rows][cols]) );
but in your case you want to return the array as a pass by ref var
int main() {
int **array;
ft_ultimate_range(&array)
}
int ft_ultimate_range(int ***array) {
*array = malloc( sizeof(int[rows][cols]) );
}
BUT
your code is kind of not using the full 2d array and the function is not returning it:
while (min < max)
{
range[0][i] = min;
i++;
min++;
}
you are only using one row here, and not even using the data in range after that, one would think the code to be irrelevant, as you are only returning len.

Why doesn't my function really initialize the array?

I'm trying to write a function that initializes an array to zero:
void InitializingToZero(int numOfrows, int numOfcols, int array[][20]) {
for (int i = 0; i < numOfrows; i++) {
for (int j = 0; j < numOfcols; j++) {
array[i][j] = 0;
}
}
}
int main() {
int num_of_rows = 3;
int num_of_cols = 3;
int array[num_of_rows][num_of_cols];
InitializingToZero(num_of_rows, num_of_cols, array);
for (int i = 0; i < num_of_rows; i++) {
for (int j = 0; j < num_of_cols; j++) {
printf("%d ", array[i][j]);
}
printf("\n");
}
}
And I get this output:
0 0 0
0 0 0
268501009 0 4200656
The error is
int num_of_rows = 3;
int num_of_cols = 3;
Then you pass the array with column field 20. For this reason the array is not initialized properly. That's where the problem lies.
You should do this
void InitializingToZero(int numOfrows, int numOfcols, int array[][numOfcols]) {
how can i do it if just know that the max size of the array it's can be 20x20, and the numOfrows, numOfcols are inputs from the user?
Then you do this
#define MAXSIZE 20
int array[MAXSIZE ][MAXSIZE];
..
InitializingToZero(num_of_rows, num_of_cols, array);
And the funcion would be
void InitializingToZero(int numOfrows, int numOfcols, int array[][MAXSIZE]) {
I DO know Quentin's response is the right one but why so much complexity for setting a memory area to 0?
int main( void ) {
const int COLS_AMOUNT = 3;
static const int ROWS_AMOUNT = 3;
int num_of_rows = ROWS_AMOUNT;
int num_of_cols = ROWS_AMOUNT;
int array[ROWS_AMOUNT][COLS_AMOUNT];
/* Set to 0 */
(void)memset( (void*)array, (int)0, sizeof( array ) );
/* Then check previous set in decreasing order... */
while( num_of_rows-- ) {
while( num_of_cols-- ) {
printf( "array[%d][%d]:%d ",
num_of_rows,
num_of_cols,
array[num_of_rows][num_of_cols] );
}
printf("\n");
}
}
By declaring your array as
int num_of_rows = 3;
int num_of_cols = 3;
int array[num_of_rows][num_of_cols];
you are creating a Variable Length Array (VLA) of size [3][3]. But the function parameter is declared as an array [][20].
For proper array parameter passing the first size does not matter (hence the empty []), but the second (and further, if any) sizes must match exactly. By creating that mismatch between [3] and [20] you are effectively lying to your function. The behavior is undefined. The compiler cannot detect and report such mismatches in case of VLAs since their actual sizes are generally not known at compile time.
The problem in your code is easy to fix: just declare the function parameter as a properly sized VLA
void InitializingToZero(int numOfrows, int numOfcols,
int array[numOfrows][numOfcols])
and leave everything else unchanged. (The first size [numOfrows] can be left "empty" as [], but I decided to spell it out for better clarity.)

Maximum vector value function problems

The function I'm making is supposed to return to the maximum value in a vector, and I'm stumped as to why it's not working, here is the code:
float max(float vec[], int len) {
int i;
float max;
for (i = 0; i < len; i++) {
if (vec[i] > max) {
max = vec[i];
}
}
return max;
}
max is uninitialized and using uninitialized variables leads to undefined behavior.
float max = vec[0];// Initialize max before using it
You did not initialize local variable
float max;
You could do it the following way
float max = vec[0];
Also the function has a problem when the second parameter is either equal to 0 or is a negative value.
The general approach is to return the index of the maximum element and in the caller to compare the returned index with the value of the second parameter. If they are equal then the array is empty. Otherwise the index points to the maximum element.
So the function could be written the following way
size_t max_element( const float vec[], size_t len )
{
size_t max = 0;
size_t i = 1;
for ( ; i < len; i++ )
{
if ( vec[max] < vec[i] ) max = i;
}
return max;
}
and in the caller you could write
float vec[] = { /* some initializers */ };
size_t max = max_element( vec, sizeof( vec ) / sizeof( *vec ) );
printf( "The maximum value is &f for element with index %zu\n", vec[max], max );

Resources