C program printing unexpected output - c

I have the following C program:
#include <stdio.h>
void setArr(int, int);
int *arr[10]; // array of 10 int pointers
int main(int argc, char *argv[])
{
int i;
setArr(0, -10);
setArr(1, 100);
setArr(2, 200);
setArr(3, 300);
setArr(4, 400);
for (i = 0; i < 5; i++)
printf("arr[%d] -*-> %d %d\n", i, *arr[i], **(arr + i)); /* should be -10,100, 200,300,400 */
return 0;
}
/* set arr[index], which is a pointer, to point to an integer of value v */
void setArr(int index, int v)
{
int i = v;
arr[index] = &i;
}
It gives the following output:
arr[0] -*-> 400 400
arr[1] -*-> 400 400
arr[2] -*-> 400 400
arr[3] -*-> 400 400
arr[4] -*-> 400 400
What I understand is that each element in the arr is a pointer and it will point to the location of the variable i created inside the function.
I am not sure how it could be consistently returning 400 always
What could be the reason for this output and how to correct it?

The definition int i = v; inside a function automatically reserves memory for i. When execution of the function ends, the memory reservation is released.
Once the memory reservation is released, the C standard does not guarantee the value of any pointers to the memory, and you should not use those values.
Each time you call setArr, the memory is reserved and then released. A common result is that the same memory is used as it is reserved, released, reserved, released, and so on, and that the pointer appears to point to the same location. Then you have set every element of arr to point to the same location. However, optimization and other actions by the compiler can produce other behaviors.
Of course, that location can hold only one value at a time, so only one value is seen in it at after the calls to setArr.

Your code makes no sense.
For starters, in C, the address of a local variable like i will not be valid once the function containing it exits.
This means all pointers in your array are not valid outside setArr.
Second, C compilers usually allocate local variables on the stack, which means i would likely be at the same address for every call to setArr, so the output you are seeing is perfectly logical.
The value of i gets overwritten every call, and because you print it immediately after last call to setArr the memory, though technically free, has not been overwritten yet.
So, by luck, you get to see the result of last call to setArr in all your printf calls.

Related

Memory allocation using for loop

My Doubt is regarding only memory allocation so don't think about program output
#include<stdio.h>
int main(){
for(int i=0;i<20;i++){
char *str=malloc(sizeof(char)*6); //assuming length of each string is 6
scanf("%s",str);
insertinlinkedlist(str);
}
}
whenever i allocate memory here as shown above only the base address of char array will pass to linked list,and that is the memory block allocated for char array is inside main only and i am storing the base address of that array in str which is local to main and is passed to insetinlinkedlist
I want to ask whenever memory is allocated inside loop than why the number of
memory blocks(no of char arrays declared ) are created equal to n (number of time loop runs) since variable name is same we should be directed to same memory location
Note I have checked in compiler by running the loop all the times when loop runs memory the value of str is different
is The above method is correct of allocating memory through loop and through same variable "Is the method ensures that every time we allocate memory in above manner their will be no conflicts while memory allocation and every time we will get the address of unique memory block"
Now above doubt also creates a doubt in my mind
That if we do something like that
int main(){
for(int i=0;i<n;i++){
array[50];
}
}
then it will also create 50 array inside stack frame
malloc returns a pointer to the first allocated byte. Internally it keeps track of how much memory was allocated so it knows how much to free (you do need to insert calls to free() or you'll leak memory, by the way). Usually, it does this by allocating a little bit of memory before the pointer it gives you and storing the length there, however it isn't required to do it that way.
The memory allocated by malloc is not tied to main in any way. Currently main is the only function whose local variables have a pointer to that memory, but you could pass the pointer to another function, and that function would also be able to access the memory. Additionally, when the function that called malloc returns, that memory will remain allocated unless manually freed.
The variable name doesn't matter. A pointer is (to first approximation) just a number. Much like how running int a = 42; a = 20; is permitted and replaces the previous value of a with a new one, int *p = malloc(n); p = malloc(n); will first assign the pointer returned by the first malloc call to p, then will replace it with the return value of the second call. You can also have multiple pointers that point to the same address:
int *a = malloc(42);
int *b = malloc(42);
int *c = a;
a = malloc(42);
At the end of that code, c will be set to the value returned by the first malloc call, and a will have the value returned by the last malloc call. Just like if you'd done:
//assume here that f() returns a different value each time
//it's called, like malloc does
int a = f();
int b = f();
int c = a;
a = f();
As for the second part of your question:
for(int i=0;i<n;i++){
int array[50];
}
The above code will create an array with enough space for 50 ints inside the current stack frame. It will be local to the block within the for loop, and won't persist between iterations, so it won't create n separate copies of the array. Since arrays declared this way are part of the local stack frame, you don't need to manually free them; they will cease to exist when you exit that block. But you could pass a pointer to that array to another function, and it would be valid as long as you haven't exited the block. So the following code...
int sum(int *arr, size_t n) {
int count = 0;
for (size_t i = 0; i < n; i++) {
count += arr[i];
}
return count;
}
for(int i=0;i<n;i++){
int array[50];
printf("%d\n", sum(array, 50));
}
...would be legal (from a memory-management perspective, anyway; you never initialize the array, so the result of the sum call is not defined).
As a minor side note, sizeof(char) is defined to be 1. You can just say malloc(6) in this case. sizeof is necessary when allocating an array of a larger type.

Pass by reference for pointers in C

I was trying to understand the concept of passing by reference. When I do this,
#include<stdio.h>
int recent (int *a)
{
*a = 20;
return 0;
}
int main()
{
int bee;
bee=5;
int *val = &bee;
printf("Value is %d\n", *val);
recent(val);
printf("Now Value is %d\n", *val);
return 0;
}
Basically I am making the pointer val point to the memory location of bee, and then when I pass it to recent function, and change the value, that change gets reflected in the calling function, so the value changes to 20. But when I do this,
#include<stdio.h>
int check = 20;
int recent (int *a)
{
a = &check;
return 0;
}
int main()
{
int bee;
bee=5;
int *val = NULL;
recent(val);
printf("Now Value is %d\n", *val);
return 0;
}
I get segmentation fault.
Is it because I didn't initialize the pointer to point to any location, and then I passed the value to recent function, and even though I made it point to a memory location (check variable), the calling function didnt catch that because I was passing by value?
Is this completely true or I misinterpreted something and got lucky with the answer?
Your problem is that you are printing the output of dereferencing the pointer val in the main function. The value of the pointer val in the main function is NULL. Thus the program is trying to print the thing at memory location 0, which is inaccessible to your program and results in a segmentation fault.
First you create the val pointer and assign it the value NULL.
int *val = NULL;
Then you call recent, passing it the pointer val, which still holds NULL.
recent(val);
Finally you print *val. val still holds NULL, and the * operator tells the compiler to "dereference" val, meaning to use the value of the thing that val is pointing to.
printf("Now Value is %d\n", *val);
In response to the question of whether your description is correct, the answer is sort of, but your description is imprecise. You made the function's copy of the pointer point to something. When you implement a pass-by-reference function in C using pointers, you are still passing the pointers themselves by value: a copy of the pointer is made, pushed onto the stack, and sent to the function. If you update the value of the pointer in the called function, the value of the pointer in the calling function will not be changed.
The reason has to do with your function recent(). When you pass in "a" you are passing in an int* (i.e. int pointer) which is an address to a location in memory. However, "a" as you have it, is local to this function (the pointer is pass by value).
Thus when you set "a = &check", you are only changing the local pointer value. As soon as recent() returns, "a" goes out of scope. In this context, you are never changing what "a" actually points to.
Thus, you segfault because val is still null, and you are trying to dereference a NULL pointer.
val is still a null pointer after leaving the function. The pointer itself is (as you correctly guessed) only passed by value, not by reference. Inside the function you are only modifying the pointer (which only lives insides the function), not the pointer target.
Besides that, please be careful with passing around memory locations to automatic stack variables. At least coming from a C++ background, it's considered bad style. Since you don't explicitly control the life cycle of a stack variable yourself (as you would do with malloc/free), you can easily shoot yourself in the foot by accidentally dereferencing pointers which have already been cleaned from the stack.
Is it because I didn't initialize the pointer to point to any location,
Code well initialized with int *val = NULL;, yet NULL is not a valid location. It isn't the NULL is a location or not. It is the NULL is the null pointer constant. As a null pointer, it "is guaranteed to compare unequal to a pointer to any object or function."
... and even though I made it point to a memory location (check variable), the calling function didn't catch that because I was passing by value?
Yes. With a = &check;, only the local a was affected, not the val in which a was copied from as the actual augment val was passed by value (copied) to the formal parameter a.
Is this completely true ...
IMO: Yes
... I misinterpreted something and got lucky with the answer?
It appears no misinterpretation. Lucky - hard to rate.
Here is what is going on in your code:
#include<stdio.h>
int check = 20;
int recent (int *a)
{
a = &check;
return 0;
}
int main()
{
// memory is allocated to hold an integer
int bee;
// the number 5 is written into that memory space
bee = 5;
// memory is allocated to hold a memory address
// the value of null (which is a invalid address) is written into it
int *val = NULL;
// more memory is allocated to hold a memory address (int* a)
// the address in val (which is null) is written into it
// the new memory address (a) now points to the address of check
recent(val);
// val is still NULL
// BOOOM!
printf("Now Value is %d\n", *val);
return 0;
}
Long story short, you are correct! :)
It's basically what all have answered. It's because you are passing the address pointed by pointer a using Pass By Value method. That is your sending in a copy of the address. If you want the second code to work you need to change the code to the following,
#include<stdio.h>
int check = 20;
int recent(int **a)
{
*a = &check;
return 0;
}
int main()
{
int bee;
bee = 5;
int *val = NULL;
recent(&val);
printf("Now Value is %d\n", *val);
return 0;
}
That is you have to Pass the address pointed by a by using C version of "Pass By Reference".

Why the pattern of data appears in memory when I use `malloc()`?

I have a simple code:
#include <stdio.h>
#include <stdlib.h>
int main(void){
char *str = (char *) malloc(4*sizeof(char));
int i;
for(i = 0; i < 64; i ++)
printf("%d, %ld, %d, %c\n", i, (long) &(str[i]), (int) str[i], str[i]);
return 0;
}
I allocate a memory into str using malloc() which is available to save 4 letters in str[0], ..., str[3]. I know that malloc() does not initialize its memory while calloc() does.
This program prints str[i] with i, address of str[i], value of str[i], letter of str[i], in order. (I use 64-bits Ubuntu, hence address is long type.)
As expected, addresses are quite different for every time I run the program. But I wonder that why str[24], str[25], and str[26] are -31, 15, 2, repectively, and other values are all 0 as you can see below:
(Note that without option -O0 gives same result.)
How can memory has same sequence (0,0,...,0,-31,15,2,0,0,...) even though only first four 0s in that sequence are allocated and others are out of care?
As you just have pointed out, malloc() doesn't initialize memory (by the way, even if it would, starting from str[4*sizeof(char)] it wouldn't be initialized because it's already out of range).
This means that you print out data that was at this memory location before. It's undefined behaviour so strictly unpredictable.
The fact that you see the same value, could be a coincidence. But if repeatable, and always with the same values, it most probably traces of the what the OS and the standard library did to initialize the environment of your process before giving control to your main().
There is a related SO question about uninitialized variables on stack. The principle of unitialized data giving access to remanent value is similar here, only that it's on the heap.
Here an experiment : a small programme to try to show you the kind of thing that could happen (attention: it's implementation dependent):
int main() {
int i;
// first part ================
char *p=(char*)malloc(100); // allocate a region in memory
for (i=0; i<100; i++) // initialize it to 0
p[i]=0;
strcpy (p+10, "Christophe"); // put some value womewhere in the middle
free(p); // release memory
// second part ============
char *q= (char*)malloc(100); // innocently allocate new memory
// and display its content
printf ("%ld==%ld ? %c%c%c\n", (long) p, (long)q, q[10],q[11], q[12]);
return 0;
}
So you could imagine that something like the first part of this code could be run during the initialization sequence of the standard library (could be at startup of the programme, or the first time you call malloc()).
Here a live demo of this code.

"Visualization" of dangling pointer

While learning pointers I tried pointer declarations/dereferenciations.
#include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int *call() {
int a = 3;
return &a;
}
int main() {
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
Sleep(2000);
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
Sleep(2000);
printf("call* is: %d\n", *call());
printf("call is: %p\n", call());
return 0;
}
So "obviously" the "a" is a local variable.
But my problem is,
when I'm reading out the address of "a", it's always the same address.
Why is that like this?
PS: I'm running a prime-number-calculator in the background to fill up as much memory as possible and I put in the "Sleep" to make the program wait, but still the address of "a" is always the same.
a is located on the stack of the current thread : every time the function call() is run, it "allocates" 4 bytes on the stack to stock a, return the address and then "frees" the space it uses on stack (it is not actually allocating/freeing anything, just offsetting the stack pointer).
So if you call it several times in a row, the state of the stack on input of the function will be exactly the same, so the actual address of a on the stack the same every time (please note that this address is invalid as soon as you exit the function).
You should do something like
int * call2(){
int a = 0;
int *b = call();
printf("%d",a);
return b;
}
and then
int *a = call();
int *b = call2();
You will see a and b will be different (the printf is there to make sure the compiler does not optimise anything away)
Since the stack is local to the current thread (not influenced by other processes/threads), your prime number calculator and Sleep are to no use at all.
"call" is to return a pointer to a variable? The problem here is that "a" is not statically allocated, but is on the stack. You can return its address at the moment (which may or may not be the same address, depending on whether "call" is invoked at the same depth each time), but there's no guarantee of what that address is pointing to once you return from "call". You put a 3 in it during the call, and that may be overwritten by something else by the time you get around to looking at the contents of that address.

pointer and which is pointed by the pointer

Update : Sorry, just a big mistake. It is meaningless to write int *a = 3; But please just think the analogy to the case like TCHAR *a = TEXT("text"); (I edited my question, so some answers and comments are strange, since they are for my original question which is not suitable)
In main function, suppose I have a pointer TCHAR *a = TEXT("text"); Then it excutes the following code:
int i;
for (i = 0; i < 1000; i++) {
a = test(i);
}
with the function TCHAR* test(int par) defined by:
TCHAR* test(int par)
{
TCHAR *b = TEXT("aaa");
return b;
}
My question is, after executing the above code, but before the program ends, in the memory:
1. the pointer `a` remains?
2. The 1000 pointers `b` are deleted each time the function test(...) exits ?
3. But there are still 1000 memory blocks there?
In fact, my question is motivated from the following code, which shows a tooltip when mouse is over a tab item in a tab control with the style TCS_TOOLTIPS:
case WM_NOTIFY
if (lpnmhdr->code == TTN_GETDISPINFO) {
LPNMTTDISPINFO lpnmtdi;
lpnmtdi = (LPNMTTDISPINFO)lParam;
int tabIndex = (int) wParam; // wParam is the index of the tab item.
lpnmtdi->lpszText = SetTabToolTipText(panel->gWin.At(tabIndex));
break;
}
I am thinking if the memory usage increases each time it calls
SetTabToolTipText(panel->gWin.At(tabIndex)), which manipulates with TCHAR and TCHAR* and return a value of type LPTSTR.
Yes, the pointer a remains till we return from the main function
The variable b (a 4-byte pointer) is automatic. It is created each time we call test function. Once we return from it, the variable disappears (the pointer). Please note, the value to which b points isn't affected.
No. In most of the cases, I think, there will be only one block allocated during compilation time (most likely in the read-only memory) and the function will be returning the same pointer on every invocation.
If SetTabToolTipText allocates a string inside using some memory management facilities new/malloc or some os-specific, you should do an additional cleanup. Otherwise there'll be a memory leak.
If nothing like this happens inside (it's not mentioned in the documentation or comments etc), it's most likely returning the pointer to some internal buffer which you typically use as readonly. In this case, there should be no concerns about a memory consumption increase.
You dont allocate any memory so you don't have to worry about memory being freed. When your vaiables go out of scope they will be freed automatically. In this function
int test(int par)
{
int *b = par;
}
you don't have a return value even though the function says that is will return an int, so you should probably do so as in this line
for (i = 0; i < 1000; i++) {
a = test(i);
}
you assign to a the value that is returned by test(). Also
int* a = 3;
int* b = par;
are asking for trouble. You are assigning integer values to a pointer variable. You should probably rethink your above code.
Pointer should contain adress... so int* a = 3 is something meaningless... And in function you don't allocate memory for int (only for par variable, which then destroy when the function ends), you allocate memory for storing adress in int* b, this memory also free when the funciton ends.

Resources