Intermittent failure with printing from a struct pointer [duplicate] - c

This question already has answers here:
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 6 years ago.
I managed to condense the code where the problem occurs to this:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef struct
{
double height;
double hello;
}Variables;
void information(Variables **Constants);
int main()
{
Variables *Constants=NULL;
information(&Constants); //Assigns values to the structure pointer
printf("Height %lf \n",Constants->height); //These print correctly only
printf("hello %lf \n",Constants->hello); //intermittently
return(0);
}
void information(Variables **Constants) //Assigns values structure pointer
{
Variables *consts,constants;
constants.height=10;
constants.hello=20;
consts=&constants;
*Constants=consts;
printf("Height %lf \n",constants.height); //These always print correctly
printf("hello %lf \n",constants.hello);
return;
}
From what i understand, this code should create a structure pointer in main, *Constants. This pointer is then passed into the function using information(&Constants). In information() another pointer is created and assigned a structure variable. The variable is then filled and the pointer is assigned to *Constants, allowing the entire struct to then be passed back to main().
If i print the structure inside information(), the values are correct. However if i print the values in main() the values are sometimes correct, or they print random numbers. Any help in understanding this would be appreciated.

You are returning a local variable from function. this is causing problem.
when the program exists from function information() the variable constants whose address you use in main is already out of scope.
To solve this problem you need to create the object in function information() using dynamic allocation. and deallocate this memory dynamically allocated in main.

Related

Function seems to change where pointer is pointing to [duplicate]

This question already has answers here:
Return address of local variable in C
(5 answers)
Can a local variable's memory be accessed outside its scope?
(20 answers)
Closed 4 years ago.
I have written following C code:
#include <stdio.h>
#include <stdlib.h>
int *getPointer(int var);
void anotherFunction();
int main ( int argc , char * argv [])
{
int *intPtr = getPointer(3);
printf("%d\n",*intPtr);
anotherFunction();
printf ("%d\n",*intPtr);
getPointer(5);
printf("%d\n", *intPtr);
return EXIT_SUCCESS ;
}
// Which problem occurs here?
int *getPointer(int var) {
int *ptr=&var;
return ptr;
}
void anotherFunction(){
// do nothing
int a [ 5 ] = { 4 , 5 , 6 , 7 , 8 };
}
The Output is:
3
7
5
I do not understand why the value of intPtr changes in the second printf() call. I would appreciate your help!
Thank you
This function is totally pointless and wrong:
int *getPointer(int var) {
int *ptr = &var;
return ptr;
}
ptr points to the local variable var (yes function parameters are more or less the same as local variables). But as soon as the function returns, that variable doesn't exist anymore. So the pointer returned by getPointer points basically to junk.
The pointer you are getting is a pointer to var local variable. And that variable is stored in the STACK (not in heap).
So, a couple of things:
Relying on pointers to STACK variables after the function call ended is just WRONG. Don't do that. Never.
The second printf is printing something in the stack that was overwritten when you called anotherFunction. This worked in this case, but this behavior is UNDEFINED (it could also lead to a SEGMENTATION FAULT).

Use of automatic variable outside its scope in C [duplicate]

This question already has answers here:
What happens when a variable goes out of scope?
(3 answers)
Closed 6 years ago.
I am studying the working of an automatic variable. I know that it is only accessible inside the block or function in which it is declared and its lifetime is within that same function or block. So the following piece of code I am trying to check.
/Declaration of header files/
void testfn(void);
int *p;
int main(void)
{
testfn();
print("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
The output is - 444
I am wondering that when the testfn(); exits,the variable x will be destroyed. Then how in main function the pointer (*p) prints 444.
How this works...or if I am missing something.
Please clarify my doubt.
Thanks
It is coincidence that the original value still remains. With another compiler, or with another compilation configuration, it could take any other value or the program could just crash.
If between the testfn and printf functions you call any other function that does something with its local variables, you might see that the 444 value is not obtained anymore. But this is just, again, coincidence.
p points to the stack where x was stored. If the memory location hasn't been used for something else you will most likely get 444.
Try to insert another function call before printing p and see what happens:
#include <stdio.h>
#include <math.h>
void foo() {
int y=123;
}
void testfn(void);
int *p;
int main(void)
{
testfn();
foo();
printf("%d\n",*p);
return 0;
}
void testfn(void)
{
int x=444;
p=&x;
}
On my machine, the output is now:
123
Since the code results in undefined behaviour, the result could be different if I try this on another platform. But you can see that undefined behaviour can lead to strange bugs.
The memory location that was previously reserved for variable x is not overwritten yet. But it may be at any time. That's why your code leads to undefined behaviour.
In the following example, the memory location that was previously reserved for variable x will be overwritten by the value that is assigned to the variable y. Since the pointer p still points to that location, *p will evaluate to this new value:
#include <stdio.h>
int *p;
void test1(void) {
int x = 444;
p = &x;
}
void test2() {
int y = 15;
}
int main(void) {
test1();
test2();
printf("%d\n",*p);
return 0;
}
The fact that the value still remains is completly coincidental (not guaranteed) because nothing has overwritten it yet.
You can not count on this, it may fail, may print garbage or may crash your program or pc even.
Don't use this, it is considered undefined behavior.

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[][].

How to understanding pointers in functions

I have two files, main.c and main2.c. My experience tells me that they should do exactly the same, but they do not.
main.c declares a global variable outside the main routine. Then, inside the main routine, a pointer is declared and defined to point to that global variable. The global variable is changed, and the value of the local variable is printed to screen.
main2.c does the same, but convolutes local-to-global definition and change of global variable value into another function, change_number.
I cannot understand why this approach fails. main.c and main2.c are the boiled down results from a few hours of bugs fixing, documentation and tutorial reading and, obviously, reading here on SO.
My understanding of pointers is what I would call rudimentary: It points to a memory location. In case of a regular variable, the pointer would point to the memory location of that variable. Several pointers can point to the same memory location, but one pointer cannot point to several locations.
There's no such thing as pass-by-reference in C, but, as far as I know, this is not pass by reference since all variable and pointers are defined outside the function. Please enlighten me.
//File: main.c
#include <stdio.h>
#include <stdlib.h>
int global_number;
int main() {
int *local_number;
local_number = &global_number;
global_number = 9;
printf("local_number = %d\n", *local_number);
return 0;
}
Output: "local_number = 9". This is the expected result.
//File: main2.c
#include <stdio.h>
#include <stdlib.h>
int global_number;
void change_number(int *number) {
number = &global_number;
global_number = 9;
}
int main() {
int *local_number;
change_number(local_number);
printf("local_number = %d\n", *local_number);
return 0;
}
Output: "Segmentation fault". This is obviously not intended. The code runs fine right up until printf().
you never initialize local_number in the second program. It does not point anywhere, and will crash when accessed. Try
int *local_number = &global_number;
then the value should change
To have change_number also initialize local_number, pass the address of local_number and change the pointed-to pointer:
void change_number( int **number ) {
*number = &global_number;
global_number = 9;
}
...
int *local_number;
change_number(&local_number);

Passing and returning arrays in C [duplicate]

This question already has answers here:
Returning an array using C
(8 answers)
Closed 8 years ago.
Following are two code snippets. One worked correctly but the other failed.
Main Function
int main
{
int *x,*y,n,*c;
//some code
c=myfunc(x,y,n);
//rest code
}
Here is the code that worked:
int * myfunc(int *a, int *b, int n)
{
int *s,i,*t;
for(i=0;i<n;i++)
s[i]=x[i]+y[i];
t=s;
return s;
}
And here is the code that doesn't work
int * myfunc(int *a, int *b, int n)
{
int s[100],i,*t;
for(i=0;i<n;i++)
s[i]=x[i]+y[i];
t=&s[0];
return t;
}
What happens here is that even though the returned value is the correct address(tested and checked) the contents seemed to get modified on its own. However this did not seem to be the case in the first scenario.
Not only that but the entire array of s[100] has different contents at the end of the executed query. Which basically means the contents of all these addresses are getting modified because of some random reason.
The compiler used was Turbo C.
EDIT
Question in Straight forward terms:
Why does the contents of s when initialized as s[100] get reset after returning and where as contents of s when initialized as *s does not reset. Please note: I Have Not used malloc() or functions that has anything to do with stacks anywhere on my code.
Nothing random about it. You're returning the address of a local variable, which ceases to exist once the function returns. That space is freed up for future function calls, variables, etc.
int * myfunc(int *a, int *b, int n)
{
int s[100],i,*t;
//some operation
t=&s[0];
return t;
} // <!-- s is no longer valid after this point, so t is pointing nowhere
In the code that doesn't work, s[100] is an array on the stack, and goes out of scope when the function returns. In the working code, you don't show how s is allocated, but presumably it's with a malloc, or some other non-stack allocation.
In general, you should not return pointers to stack variables because the stack variables will get overwritten as soon as the function returns.
PS. get a real compiler already :)

Resources