Inconsistent array values when initialized from fscanf() in C - c

If a multi-dimensional array in main() gets initialized from a functions pointer like this:
#include <stdio.h>
void arrayfunction(int (*n)[3][3])
{
(*n)[0][2]=7;
printf("Function output: %i\n", *n[0][2]);
}
main()
{
int y[3][3];
arrayfunction(&y);
printf("Main output: %i \n",y[0][2]);
return(0);
}
then array in main() will hold the correct value, but the output from the pointer in arrayfunction() will not:
Function output: 4195805
Main output: 7
However, if the function initializes the array in main() through the functions pointer via fscanf():
#include <stdio.h>
void readSchedule(int (*s)[3][3]){
FILE *schedule;
schedule=fopen("/var/schedule.conf","r");
fscanf(schedule,"[%i,%i,%i,%i]\n",s[0][0], s[0][1], s[0][2], s[0][3]);
fclose(schedule);
printf("Function output value: %i\n",*s[0][2]);
}
main()
{
int x[3][3];
readSchedule(&x);
printf("Main output value: %i\n ",x[0][2]);
return(0);
}
Then the values are reversed, the pointer local to the function will output the correct value, but the array it points to in main() will not:
Function output value: 7
Main output value: 0
Why do the correct values only show up in the array local to main() in the first example, but only show up in the pointer local to the function in the second example?

Check the operator precedence and notice the difference in the two lines using n in arrayFunction
(*n)[0][2]=7;
printf("Function output: %i\n", *n[0][2]);
The parenthesis are critical here. The [] operator has a higher precedence than * (http://en.cppreference.com/w/cpp/language/operator_precedence). If you add parenthesis in the printf line you'll see what you expect.
More or less the same thing is going on in with the fscanf example. The compiler is treating s[0][0] as a pointer to an int (like this *(s[0][0])) so the data is getting written to an undefined area.
If you use a memory debugging program like valgrind you'll see tons of errors.

The problem in the first example is solved in the syntax of the pointer to array argument in the printf statement inside the function by changing the precedence from:
printf("Function output: %i\n", *n[0][2]);
to
printf("Function output: %i\n", (*n)[0][2]);
In the second example, fscanf() was apparently stuffing values directly into *s[][] instead of indirectly initializing the array in main() that *s[][] points to. So instead of this:
fscanf(schedule,"[%i,%i,%i,%i]\n",s[0][0], s[0][1], s[0][2], s[0][3]);
the syntax needs to be this:
fscanf(schedule,"[%i,%i,%i,%i]\n",&(*s)[0][0], &(*s)[0][1], &(*s)[0][2], &(*s)[0][3]);
in order to reach through *s[][] and place the values in y[][].

Related

c void main function? returning 16 value

I am writing a c program with void main function in code blocks.
I just write return with no value.
The program is as below:
#include<stdio.h>
void main (void)
{
printf ("ali tariq\n");
return;
}
However, in the console window the program returns the value 16 in the console window. "Process returned 16"
I want to know why it is returning this value?
How can i utilize this value in windows using codeblocks?
Thanks
In (hosted) C the main function must return an int (C11§5.1.2.2.1[1]). By declaring it with a return type of void, and not specifying any return value you invoke undefined behaviour. This means the compiler is free to return anything and in your case it turns out to be 16.
You are not free to declare the return type of main as you wish. Why?
BECAUSE YOU DIDN'T WRITE THE CODE CALLING main(). Sorry 'bout the shouting, but someone else wrote that code and placed it in crt0.o or so. Your main() is linked against that code and it can't just return what it wants because that code expects an int. Always. It's already written and compiled. You understand this subtle point?
Because the C Standard says so. See other answer by Kninnug for Chapter and Verse.
In other words, your code invokes undefined behavior and it should be no surprise to find a garbage value where no value was provided.
So you expected a warning from the compiler? The better ones indeed will catch this with the right options. E.g. gcc and clang support -Wmain-return-type.
You should not use void main(), use int main() instead.
The program has undefined behavior. First of all according to the C Standard main without parameters shall be declared like
int main( void )
You declared the function as having return type void. In this case the process that starts the program can not get a valid return code of the program.
Just because a function is declared as void doesn't mean it won't return anything. On the x86, for example, a lot of calling conventions specify that the value in the register EAX after a function call is the return value of the function. So, if you have a C function that is declared void but the machine code for the function changes the value of EAX, that will get treated as the return value for the function.
EVERY "normal" program that terminate execution WITHOUT errors, must return ZERO.
So, your program must be:
#include<stdio.h>
int main (int argc, char *argv[]) // your program may have command line parameters
{
printf ("ali tariq\n");
return 0; // Program terminate with NO ERRORS
}
However there are cases when one program may terminate WITH errors.
Let's suppose this:
#include<stdio.h>
void main (int argc, char *argv[])
{
// program to make a division between two numbers
double a, b, res;
a = b = res = 0.0;
printf ("Enter 1st number: ");
scanf ("%lf", &a);
printf ("Enter 2nd number: ");
scanf ("%lf", &b);
if (b == 0) return 1; // division by '0' then return ERROR (any number != 0)
printf ("%f / %f = %f", a, b, a/b);
return 0; // NO ERROR
}
Now you may ask: «But where is the return value evaluated?
Answer: «By the Operating System.»
One batch file may run your program and read the integer YOU returned in the environment variable 'ERRORLEVEL'

Why does my program display the Array address instead of its contents?

My C program consists of an array called 'test_var'. It has another integer array 'arr_int' that consists of a set of integer numbers. My code looks something like this:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
int State(var);
int main()
{
int arr_int[3] ={1000, 1001, 1002, 1003};
int var;
int *test_var[4]={0};
State(var)
{
int i;
for(i=0; i<4; i++){
test_var[i] = arr_int[i];
i++;
}
return test_var[var];
}
printf("Enter a number between 0 and 3\n");
scanf("%d",&var);
State(var);
printf ("The array structure is %d", test_var[var]);
return 0;
}
However now when I try to print the returned value array test_var for the user input var=0 instead of the whole array(1000) I just get 0. What am I doing wrong here ? COuld somebody please tell me? Am I dereferencing the array in a wrong way?
EDIT : the code without the typo:
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
int State(var);
int main()
{
int *arr_int[3] ={1000, 1001, 1002, 1003};
int var;
int *test_var[4]={0};
State(var)
{
int i;
for(i=0; i<4; i++){
test_var[i] = arr_int[i];
i++;
}
return test_var[var];
}
printf("Enter a number between 0 and 3\n");
scanf("%d",&var);
State(var);
printf ("The array structure is %d", test_var[var]);
return 0;
}
In your case,
the statement
test_var[i] = arr_int[i];
is wrong. test_var[i] is of type int *, and arr_int[i] is of type int, and they are not really compatible. To quote the standard, chapter §6.3.2.3
An integer may be converted to any pointer type. Except as previously specified, the result is implementation-defined, might not be correctly aligned, might not point to an entity of the referenced type, and might be a trap representation.
Then, you're using another statement like
printf ("The array structure is %d", test_var[var]);
%d expects an int argument, but you're supplying an int *. Pure undefined behaviour.
After that, int State(var) relies upon the older concept of default-to-int, which has been made invalid in C99 onwards.
In an array of 3 elements, you're supplying 4-member initializer list. Useless and confusing.
That said, FWIW, you're using a nested function, which is also not a part of standard C. It is supported as a GCC extension.
EDIT:
As per the comments, even if your arr_int is an array of of type int *, the initializers do not provide a seemingly valid value for the pointers to be dereferenced. That means, you cannot access the memory pointed to by those pointers, they are most likely to reside outside of the allocated memory area of your process and hence, invalid.
Nevertheless, for the point 2, mentioned earlier, the code is UB.
int arr_int[3] ={1000, 1001, 1002, 1003};
Array is of size 3 you initialize it with 4 elements.
Also the nested function is supposed to create a problem.They are supported as an extension in GNU C.
Note-Though you can declare a function inside of a function, but it's not a nested function.
EDIT
Your second code when you give input as 0 and 2 it seems to give correct output but when input is 1 or 3 it gives as 0. Surely it doesn't behave as intended.
int *arr_int[3] ={1000, 1001, 1002, 1003};
int *test_var[4]={0};
Why did you declare pointers instead of arrays? And why arr_int[3] is initialized with 4 integers?
It should be like this.
int arr_int[3] ={1000, 1001, 1002};
int test_var[4]={0}

Checking pointer address and value from a function

I'm a beginner to C and have been reading a book called "Understanding and Using C Pointers" and ended up running into a problem with using the printf function.
When using debug_p, it turns out that the address of the pointer num_p is different but exact to num in debug, but it returns the correct value when attempting a printf within main().
My question is, why is this so? Is there an appropriate way to do a printf within a function and have a correct address of a pointer?
#include <stdio.h>
void debug(int num)
{
printf("Address of num: %i Value: %i\n", &num, num);
}
void debug_p(int *num_p)
{
printf("Address of num_p: %i Value %i\n", &num_p, num_p);
}
int main()
{
int num=11;
int *num_p=&num;
printf("Address of num: %i Value: %i\n", &num, num);
printf("Address of num_p: %i Value: %i\n\n", &num_p, num_p);
debug(num);
debug_p(num_p);
return 0;
}
Output from main():
Address of num: 2358860 Value: 11
Address of num_p: 2358848 Value: 2358860
Output from debug, then debug_p:
Address of num: 2358816 Value: 11
Address of num_p: 2358816 Value 2358860
When you pass a variable to a function, you only pass the value of this variable. You never pass the address, because a new variable is created in that function. The parameters that you see in the signature of the function are all local variables, just like you would write them in the function body. These parameters are filled with the value that you pass when you call the function - but again, you are just passing the value to new variables.
void function(int a) { printf(a); }
int a = 5;
function(a);
In this example, there exist two distinct variables which have completely different addresses. They just have the same value (which is 5), but their addresses are very different.
The same happens in your debug function: num in there is not the same variable as num in main, they just have the same value (because you "gave" the value of num in main to num in debug), but not the same address. Now since num_p in debug_p still points to num in main and not to num in debug, the addresses are different.
The reason why num and num_p have the same address in both functions is because of how the stack works: The first call to debug allocates a variable on the stack. Then, when the function returns, the stack is freed again. Now you call debug_p, and therefore another variable is allocated. It will use the same place in memory as before, because the stack is built up in the same way.

Module function not returning an answer

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
func (int x, int apple);
int main()
{int x,apple;
scanf("%d",x);
func (x,apple);
if (apple==0)
printf("Yes");
else if (apple==1)
printf("no!");
}
func (int x,int apple )
{
if ((x%7)==0||(x%11)==0||(x%13)==0)
apple=0;
else
apple=1;
}
The idea of the whole thing is that the function tests whether the entered value x is a multiple of 7,11 or 13, and gives a result.
The function works just fine (In terms of that the compiler doesn't detect an error and launches just fine) but s what I get on my compiler's window (After I enter any value) is that the process returned 1 and nothing else. And prior to that, it gives me a windows error and that the project I am working on crashed.
I am pretty much forced to use pointers, so what am I doing wrong?
Appreciate the help!
There is a mismatch between the format specifier "%d" and the argument type being provided to scanf(), an int is specified when it must be an int*: this is undefined behaviour. Pass the address of x to scanf() and ensure x is assigned a value by checking return value of scanf() which returns the number of successful assignments:
if (scanf("%d",&x) == 1)
{
}
State return type of void for func().
Pass the address of apple to func() (and change argument to int* apple) so any change made to apple within func() is visible to the caller:
void func (int x, int* apple)
{
/* Dereference 'apple' for assignment. */
*apple = 0;
}

De-Referencing a pointer passed from another function to main()

I'm trying to use a separate function to input data using scanf() (outside of main). This new function is supposed to print a line and then receive input from the user. However something appears to be going awry between the scanf in the function and the printf() function in the main that I am testing it with.
I believe that I am receiving a pointer from the function but certain compiler warning are making me wonder if my assumption about the pointer is even correct.
I am confused by the output of this code:
#include <stdio.h>
void set_Info(void);
int main()
{
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
return 0;
}
void set_Info(void) /* start of function definition */
{
int scanNum;
printf("Scan test, enter a number");
scanf("%d",&scanNum);
}
If I provide a number, say 2, the result of the printf statement in the main() is:
2665560
Now, in so far as I am able to tell that output appears to me like a memory address so what i attempted to do to fix that is dereference the pointer in main like so :
int scanNum = 0;
int scanNumHolder;
set_Info();
scanNumHolder = *scanNum;
printf("%d", &scanNumHolder);
I believe that this code makes scanNum variable to become assigned to the dereferenced value of scanNum. However I get the same output as above when I do this. Which leads me to believe one of two things. Either that I am not correctly dereferencing scanNum, or that scanNum is not in fact a pointer at all in this situation.
The most common error I receive from the compiler is:
error: invalid type argument of unary ‘*’ (have ‘int’)
Which makes sense, I suppose, if I'm attempting to treat an int value as a pointer.
If it is the case that scanNum is not being dereferenced correctly, how can I achieve this?
Thank you for the help
*Update
Thanks for the help.
Just to recap
My set_info function needs to be passed an address parameter. The reason an address parameter has to be used is because the local memory of a function is erased after the function call ends. So in order to do work a variable declared in the main function, I pass the address of the variable in question so that when the function ends the changes are not lost.
Inside the main function, when set_info is called with &scanNum as the argument, it passes a reference tp the variable so that it can be assigned the value generated by the scanf statement in the function.
I realize that what I was doing wrong as correctly pointed out by the awesome people of SO, is that I am trying to call set_info like it returns a value but in fact changes the variable like I actually want.
Thanks again for the help!
This function:
void set_Info(void)
{
int scanNum;
scanf("%d", &scanNum);
}
reads the integral number from the standard input and stores it into scanNum variable, which is local variable with automatic storage duration that exists only within the scope of this function.
And the body of your main:
int scanNum = 0;
set_Info();
printf("%d", &scanNum);
defines a local variable called scanNum, then calls a set_Info() function which doesn't affect scanNum defined in main in any way and then it prints the address of scanNum variable.
This is what you are trying to do:
void set_Info(int* num)
{
// read an integer and store it into int that num points to:
scanf("%d", num);
}
int main()
{
int scanNum = 0;
// pass the address of scanNum to set_Info function so that
// changes to scanNum are visible in the body of main as well:
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
I also recommend you spend more time reading some book with C basics before you'll continue programming :)
I would pass in the variable into your set_Info function, so that it knows where to save the data. This would then allow you to scan multiple values, and you would simple increment the pointer. Be sure to pass the variable address into set_Info() using &variableName, since that function expects a pointer
#include <stdio.h>
void set_Info(int *pScanNum);
int main()
{
int scanNum = 0;
set_Info(&scanNum);
printf("%d", scanNum);
return 0;
}
//Pass in the pointer to scanNum
void set_Info(int *pScanNum)
{
printf("Scan test, enter a number");
scanf("%d",pScanNum);
}
Get rid of your ampersand! Printf wants an integer not a pointer.
printf("%d", scanNum);
And as liho said, you need to return scanNum from set_info so you can get at it outside of the function.
int scanNum = set_Info();

Resources