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

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}

Related

Inconsistent array values when initialized from fscanf() in 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[][].

Array not being passed to Function Method

I'm currently trying to pass an array of (values[3]) which it's first 3 values contain user input. However, I'm getting the error "expected int* but argument is type of int". I've tried to pass to method1, without the iteration of 'i', using the first three positions in the values array, but that's as far as I managed to attempt to fix it, any help would be much appreciated!
int main(void)
{
int i;
int values[3];
printf("Enter three consecutive numbers (With spaces between)");
scanf("%d %d %d",&values[0],&values[1],&values[2]);
for(i=0;i<3;i++)
method1(values[i]);
}
int method1(int values[3])
{
}
You cannot pass an array to a function as an array - it "decays" to a pointer. There are two issues with your code:
There is no forward declaration of method1 visible at the point of invocation, and
You are passing values[i], a scalar value in place of an array.
A forward declaration is necessary because otherwise the compiler would assume that method1 takes an returns an int, which is not true. Add this line before main
int method1(int values[]);
You could also move method1 above main to fix this without providing a forward declaration. Also, 3 inside square brackets is not necessary, because the array is passed like a pointer anyway.
If you want to pass the entire array, pass values. Of course, i becomes unnecessary:
int res = method1(values);
#include <stdio.h>
int main(void)
{
int i;
int values[3];
printf("Enter three consecutive numbers (With spaces between)");
scanf("%d %d %d",&values[0],&values[1],&values[2]);
method1(values, 3);
getchar();
getchar();
return 0;
}
int method1(int* values, int size)
{
int i;
for(i=0; i<size; i++){
printf("%d ", values[i]);
}
return 1;
}
In C, arrays are passed by reference, you can see method1's first argument is int* that refers first element of array, and second argument is size of this array.

Passing a structure (pointer to structure?) to a function

Ok so, I'm trying to write a program which numerically evaluates integrals using Simpson's 3/8 rule. I'm having issues passing the values from Integral *newintegral to the simpson() function. I'm not massively confident in my understanding of structures and pointers, and I've been reviewing the lecture notes and checking online for information all day and I still can't understand why it's not working.
At the moment when I try to build my program it comes up with a number of errors, particularly: on line 46 "expected expression before Integral" and on most of 55-63 "invalid type of argument of '->' (have 'Integral') I don't understand why the first one is occurring because all my lecturers examples of this type of thing, when passing a structure to a function just have the syntax func(Struct_define_name individual_struct_name). I thought this is what I was doing with mind (Integral being the name of the structure type and i being the specific structure) but obviously not.
I think these two problems are connected so I included all of my code for context, however the lines which actually have errors are 46 and 55-63 as mentioned above. I've probably defined the structure wrong in the first place or something though.
(Incidentally the maths in the simpson() function doesn't actually work properly now anyway, but that's not something I'm concerned about)
Also I tried looking at other similar questions but I didn't understand what the other code was doing so I couldn't extrapolate how to fix my code from that. I know this isn't very relevant to other people but I really don't understand programming well enough to try and phrase my question in a general sense...
'#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct integral {
double result, limits[2];
int degree;
double coefficients[];
} Integral;
// Prototype of function that calculates integral using Simpson's 3/8 rule
double simpson(Integral i);
// function (?) which initialises structure
Integral *newintegral() {
Integral *i = malloc(sizeof *i);
double lim1_in, lim2_in;
int degree_input, n;
printf("Please enter the degree of the polynomial.\n");
scanf("%d", &degree_input);
i->degree = degree_input;
printf("Please enter the %d coefficients of the polynomial, starting\n"
"from the highest power term in the polynomial.\n", (i->degree+1));
for (n=i->degree+1; n>0; n=n-1) {
scanf("%lg", &i->coefficients[n-1]);
}
printf("Please enter the upper limit of the integral.\n");
scanf("%lg", &lim1_in);
i->limits[0] = lim1_in;
printf("Please enter the lower limit of the integral.\n");
scanf("%lg", &lim2_in);
i->limits[1] = lim2_in;
return i;
}
int main() {
Integral *i = newintegral();
simpson(Integral i);
return 0;
}
double simpson(Integral i) {
int n;
double term1, term2, term3, term4;
for (n=(i->degree); n>0; n=n-1) {
term1=(pow(i->limits[1],n)*(i->coefficients[n]))+term1;
term2=(pow(((((2*(i->limits[1]))+(i->limits[0])))/3),n)*(i->coefficients[n]))+term2;
term3=(pow(((((2*(i->limits[0]))+(i->limits[1])))/3),n)*(i->coefficients[n]))+term3;
term4=(pow(i->limits[0],n)*(i->coefficients[n]))+term4;
}
i->result = (((i->limits[0])-(i->limits[1]))/8)*(term1+(3*term2)+(3*term3)+term4);
printf("The integral is %lg\n", i->result);
return 0;
}'
You're currently passing a pointer to a function that takes a single Integral argument.
Your prototype, double simpson(Integral i); tells the compiler "declare a function called simpson that returns a double and takes a single Integral referenced by the identifier i inside the function.
However, in main() you say:
int main() {
//declare a pointer to an Integral and assign it to the return of 'i'
Integral *i = newintegral();
//call the function simpson with i.
//However, you are redeclaring the type of the function argument, so the compiler will complain.
simpson(Integral i);
return 0;
}
Your call, simpson(Integral i); will not work because you are redeclaring the type of the function argument. The compiler will state:
:46:13: error: expected expression before ‘Integral’
What you really need is for simpson() to take a pointer to Integral as its argument. You have actually already handled this inside the function, (using i->) but your function prototype is telling the compiler that you are passing the whole struct Integral as the function argument.
Solution:
Change your function prototype as follows:
double simpson(Integral *i); // function returning double taking single pointer to an Integral named i.
...and change main() to look like the following:
int main(void) { //In C main has two valid definitions:
//int main(void), or int main(int argc, char **argv)
Integral *i = newintegral();
simpson(i);
return 0;
}
So in conclusion, your understanding of pointers is correct, but not how you pass a pointer to a function.
**Sidenote:
Remember to always build your code with all warnings enabled. The compiler will give you very useful diagnostics that will help you quickly find solutions to problems like this. For GCC, as a minimum, use gcc -Wall myprogram.c
Two obvious problems:-
Line 46 : simpson(Integral i);
...should be just simpson(i);. Putting a type there is simply an error.
And this, later:
double simpson(Integral i)
.. tells the compiler to pass in Integral object yet you use the indirection operator i.e i->limits as though you'd been passed a pointer. The easiest fix is to make the function expect a pointer, like this:
double simpson(Integral *i)

In C,how do I make this program return the address of an array,instead of address of first element?

I am really at a loss about this program.I want it to return the address of an integer array of 5 elements.But it just wont' work.How to make a C function return the address of an array instead of the address of its first element(base address)?I know both are same numerically but their types are different,that's why I ask.
Also to put it precisely, how to declare the prototype of such functions?I understand how to declare the argument part of the prototype (using abstract declarators) but just don't know how to declare the return type if we are to return addresses of arrays or functions.I only know that if we place a '*' before function name in declaration that it means the function returns a pointer to the respective primary data type like int,char or float.
#include<stdio.h>
int (*)[5]fun(int (*)[5]);
int main(void)
{
int arr[5];
printf("%u",fun(&arr));
}
int (*)[5]fun(int (*arr_add)[5])
{
return arr_add;
}
HELLO!! DANIEL FISCHER Thanks for your answer.You answered it exactly and in a concise way.But I am choosing H2CO3 's answer as that brilliant Hungarian kid took the trouble to explain it to me in detail through chat.It's really hard to pick the best answer when so many bright people are answering.Thanks everyone!!
Perhaps explaining how it works is of some use.
The idea behind C's declaration syntax is that "declaration mimics use". So you want
a function
fun( )
taking a pointer to an array of five int
fun(int (*arr)[5]) // or without argument name fun(int(*)[5])
and returning a pointer
(*fun(int (*arr)[5]))
to an array of five
(*fun(int (*arr)[5]))[5]
int
int (*fun(int (*arr)[5]))[5];
Or, you can also go from the result, that should be a pointer to an array of five int,
int (*result)[5];
and substitute result with the call (result = fun(arr))
int (*fur(arr))[5];
and then add the type of the argument/replace the argument with its type:
int (*fun(int(*)[5]))[5];
Here you are:
int (*fun(int (*arr)[5]))[5]
{
return arr;
}
If you want to return the address of the first element (as opposed to the address of the array itself), that's a different type:
int *fun(int (*arr)[5])
{
return &(*arr)[0];
}
This is wrong:
printf("%u",fun(&arr));
It should really be:
printf("%p", (void*)fun(&arr));
As for the address of the array, it is going to be the same as the address of its first element.
Now, the declaration and definition should really look like:
int (*fun(int(*)[5]))[5];
Fixed code:
#include<stdio.h>
int (*fun(int (*)[5]))[5];
int main(void)
{
int arr[5];
printf("%p\n", (void*)fun(&arr));
}
int (*fun(int (*arr_add)[5]))[5]
{
return arr_add;
}
ideone

runtime datatype working in c, how does sizeof work?

As we know, we can use int (*p)[10] to define a pointer which points to an int[10] array, so if we have p=0 and sizeof(int)==4, p+1 will be 0+10*4 = 40, this works because the compiler knows what p is when compiling.
And then what if we do it like this:
int main()
{
int sz = 10;
int (*p)[sz];
}
in other words, nobody would know the sz until the program runs there. I supposed this should not be working, but it does work..
So my question is, how it works? I mean, is there any place that store a value's type in c at runtime? If not, how this could work? Of this is just compiler-related?
I am using gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu5), and you can test it with the following code.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
int main()
{
int COL ;
int ROW ;
scanf("%d %d", &COL, &ROW);
int (*p)[COL];
int *mem = (int*)malloc(sizeof(int)*COL*ROW);
memset(mem,0,sizeof(int)*COL*ROW);
p = (int (*)[10])mem;
printf("0x%p\n", p);
printf("COL=%d\n", p+1, (((int)(p+1))-((int)p))/sizeof(int));
mem[2*COL+0] = 1;
printf("%d\n", p[2][0]);
mem[2*COL+5] = 2;
printf("%d\n", p[2][5]);
mem[6*COL+7] = 3;
printf("%d\n", p[6][7]);
p[1][2] = 4;
printf("%d\n", mem[1*COL+2]);
free(p);
return 0;
}
I hope I am not asking a stupid question nor making stupid mistake...
Pointer arithmetic on variable length array types is well defined per 6.5.6:10, which has example code very similar to yours. Per 6.5.3.4:2, when sizeof is applied to a variable length array, the operand is evaluated at runtime to determine the size, so variable length array pointer arithmetic proceeds likewise.
Variable length arrays (6.7.6.2:4) have been part of the standard since the second edition (ISO/IEC 9899:1999 as amended); they are however an optional feature that conformant implementations do not have to support (6.10.8.3).

Resources