Why is this code printing '7' - heap-memory

Why is this code printing '7'
Trying to understand how the Stack and Heap looks like and how does it looks in the memory allocation
public static void Main()
{
Cls a = new Cls();
a.v = 3;
Func(a);
Console.WriteLine(a.v);
}
class Cls
{
public int v;
}
static void Func(Cls a)
{
a.v = 7;
a = new Cls();
a.v = 2;
}
If you can attach a scatch of stack and heap with memory it will really appreciated

static void Func(Cls a)
{
a.v = 7; <----- This is modifying the Cls you create in Main function
a = new Cls();
a.v = 2; <----- This is a new and locally referenced Cls whose value is neither returned to the main function nor is a global variable
}

You're passing a pointer to the first Cls instance. The second one, created inside youre function, is an entirely different object.
In other words, you're printing a property value from the first object, the one pointed to by the a in Main().
When you're re-assigning the a variable to a new object inside your function, the a inside Main() still points to the original object.
I'm not sure I'm explaining this very well... :) Or perhaps I'm even misunderstanding the question?

Related

Unable to modify pointer variable passed as argument to a function

I have this function
int rt_exist(struct route_entry* prev_rte) {
prev_rte = rte_head; //This doen't assigns rte_head to prev_rte
return 0;
}
where rte_head is an initialized struct route_entry* pointer variable.
But in the above case "prev_rte" is not assigned the value of rte_head.
By the way ,I if I do something like this
int rt_exist(struct route_entry* prev_rte) {
struct route_entry* rte_new;
rte_new = rte_head; //But this can
return 0;
}
The above assignment occurs smoothly . The problem arises when pointer variable is passes as function argument.
It's a weird question with little details ,but can someone point me to a possible direction or something wrong I might be doing.
Consider this:
void foo (int j)
{
j = 7;
}
foo (8);
What do you expect to happen here? A function can't change a value in the caller this way.
What should happen here:
rt_exist (NULL);
For C++, you can use references:
int rt_exist(struct route_entry*& prev_rte) {
prev_rte = rte_head; //This doen't assigns rte_head to prev_rte
return 0;
}
For C, you need to pass a pointer to the thing you want to change:
int rt_exist(struct route_entry** prev_rte_ptr) {
*prev_rte_ptr = rte_head; //This doen't assigns rte_head to prev_rte
return 0;
}
Yes! in first case you are using temporary portion of a stack. But in the second case you are using allocating. Which means that you are using a portion of memory which is from heap. It will obviously affect the value. This is like a new variable in a new block. In this scope it will have the assigned value.
But in rt_exist the copy of the variable is passed. So any change in that will not affect the actual one. But you can pass it's address and change it easily like this.
int rt_exist(struct route_entry** prev_rte)
{
*prev_rte = rte_head; //This does assign rte_head to prev_rte.
return 0;
}

Update (int) variable in C inside a function [duplicate]

This question already has answers here:
How to change a variable in a calling function from a called function? [duplicate]
(3 answers)
Closed 8 years ago.
I'm trying to write a function that changes screen in my simple C snake game.
main(){
int stage = 0;
...
..
.
while(stage!=0){
//if snake hits wall
changeStage(stage);
}
}
function:
void changeStage(int stage){
stage = 1;
}
This code does not update the code, it will keep on running.
What is wrong with my code?
stage is passed by value to changeStage. stage = 1 only changes the local value of stage in changeStage, not the value of stage in main. You have to pass a pointer instead:
while (stage != 0) {
changeStage(&stage);
}
void changeStage(int *stage) {
*stage = 1;
}
C is a pass by value language. The simplest approach to accomplish what you want is to pass a reference to the variable you need to change. For example:
void changeStage(int *stage){
*stage = 1;
}
main(){
int score = 0;
int stage = 0;
...
..
.
while(stage!=0){
//if snake hits wall
changeStage(&stage);
}
}
Note: You may need to read up on pointers to fully understand the code if you are just beginning with C programming. In the example code, instead of passing the value of 'stage', you pass the location where the value of 'stage' is stored. The function can then modify the contents in the location.
C function arguments are pass-by-value. This means that instead of passing a reference to stage you are passing the value stored in it. The update you do the in changeStage function then only applies to the copy that has been made.
If you want to update a variable in another function, you will need to pass a pointer to it.
void changeStage(int* stage_p){
*stage_p = 1;
}
int main() {
//...
while(stage!=0){
//if snake hits wall
changeStage(&stage);
}
}
&stage says to take the address of stage and pass that to the function. The stage_p argument will then point to the int in the main.
*stage_p causes it to use the value pointed to by stage_p, which is stage in the main in your case.
Further reading
You are not modifying the original stage variable, but only modifying an local copy inside changeStage function.
You need to use a pointer:
void changeStage(int* stage)
{
*stage = 1;
}
using the function:
while (stage != 0)
{
// if snake hits wall
changeStage(&stage);
}
You need learn more basic concepts of C language. Pointer is an very important feature in C language.
Correct, you need to pass the pointer if you wish to change the value of the variable in main() or you can create it as global variable, that way it's accesable both in functions and in main.
static int stage = 0;
void changeStage(){
stage = 1;
}
main(){
int score = 0;
...
..
.
while(stage!=0){
//if snake hits wall
changeStage();
}
}

Confusion on memory management: global char * in C program

I have a program where I have a global char * that I'm going to constantly be changing. Right now, I set it to a value when it's NULL, and alter it when it's not. However, it's never not NULL, even if I'm setting the pointer. An example of what I'm saying:
char *a;
void function()
{
if(a == NULL)
{
a = "Test1";
}
else
{
a = "Test2";
}
}
Every time I go through this function, though, a is always null. I assume there's something I need to be doing with memory allocation, but I'm confused about where I would allocate it, and where I would free it. Thanks!
The first time function() gets called, 'a' will be NULL because global variables in C are initialized to zero.
You then set it to point to "Test1". The second time function() gets called, 'a' will still be a pointer to "Test1", not NULL, so you'll set it to "Test2". Every future call will essentially do nothing, setting 'a' to "Test2" again and again.
If that's not what you're seeing, then there is something different with your actual code compared to the code you posted above. For example, if "char *a" is inside of a function then it is a local variable, not a global, and it will be of undefined value on function entry and also lose its value every time the function exits.
The code below produced the output underneath it, as it should.
#include <stdlib.h>
#include <stdio.h>
char *a;
void function();
int main( int argc, const char *argv[] )
{
function();
function();
function();
function();
return 0;
}
void function()
{
printf( "function: a=%s", (a ? a : "NULL") );
if(a == NULL)
{
a = "Test1";
}
else
{
a = "Test2";
}
printf( " exiting a=%s\n", (a ? a : "NULL") );
}
This produces the following output:
function: a=NULL exiting a=Test1
function: a=Test1 exiting a=Test2
function: a=Test2 exiting a=Test2
function: a=Test2 exiting a=Test2
I feel a little sheepish for this. The problem was that I was forking the process, and editing the copy of the variable in the child process, without realizing that the parent process' variable was unaffected.
Sorry about that. Hope this helps someone else who runs into this.
I'm writing this as a "response" instead of a question so I can format the text better:
Q1) Does the behavior change if you initialize like this?
char *a = NULL;
Q2) what's your compiler, compiler version and OS?
Q3) are you sure there's no other code that might be messing with "a"?
==================================================
ADDENDUM:
Q: I just realized that I'm editing the variable's value in a child process after forking. Could that be the problem? – Mason
A: Only if you expect changing the variable in one process to somehow change the other process (without assigning a shared memory segment) ;)

Modifying struct members through a pointer passed to a function

for instance this code:
struct test{
int ID;
bool start;
};
struct test * sTest;
void changePointer(struct test * t)
{
t->ID = 3;
t->start = false;
}
int main(void)
{
sTest->ID = 5;
sTest->start = true;
changePointer(sTest);
return 0;
}
If I was to execute this code, then what would the output be? (i.e. if I pass a pointer like this, does it change the reference or is it just a copy?)
Thanks in advance!
Your program doesn't have any output, so there would be none.
It also never initializes the sTest pointer to point at some valid memory, so the results are totally undefined. This program invokes undefined behavior, and should/might/could crash when run.
IF the pointer had been initialized to point at a valid object of type struct test, the fields of that structure would have been changed so that at the end of main(), ID would be 3. The changes done inside changePointer() are done on the same memory as the changes done in main().
An easy fix would be:
int main(void)
{
struct test aTest;
sTest = &aTest; /* Notice the ampersand! */
sTest->start = true;
changePointer(sTest);
return 0;
}
Also note that C before C99 doesn't have a true keyword.
The only question is why do you need a test pointer in a global name space? Second is that you do not have any memory allocation operations. And you have a pointer as an input parameter of your function. Therefore structure where it points to will be changed in "changePointer".
1) First thing your code will crash since you are not allocating memory for saving structure.. you might need to add
sText = malloc(sizeof(struct test));
2) After correcting the crash, you can pass structure pointer and the changes you make in changePointer function will reflect in main and vizeversa..
3) But since you are not printing anything, there wont be any output to your program..

Structure initializing problem in C

I'm writing a program for a "Set" data structure in C.
It's working fine when one instance of Set is present, but it doesn't work when two instances of Set are present.
Also my code for removing an element is not working when the candidate is the first element.
Can someone help me?
Here is the code:
Set.h
Set.c
Test.c
First of all you passes pointer to set by value. I.e. instead of
void Set_Create (Set* set) {
set = malloc(...); // Malloc here leads to memory-leak.
//...
}
int main() {
Set *set; // Some value like 0xdeadbeef pointing somewhere
Set_Create (set);
// set have still undefined value
}
use
Set *Set_Create () {
Set *set = malloc(...);
/// ...
return set;
}
int main() {
Set *set; // Some value like 0xdeadbeef pointing somewhere
set = Set_Create ();
// set point to new memory
}
or:
void Set_Create (Set *set) {
// No malloc
/// ...
return set;
}
int main() {
Set set; // Create on stack
Set_Create (&set); // Initialize
// ...
}
I'd advice re-reading chapter on pointers (don't worry - they are considered hard but they are must for C programmers).
I suspect that you are asking us to help you with your homework, so I am not going to solve all of your code problems for you. I am only going to point out your most egregious mistake, which is the mistake you asked about -- why does the second call to your create_Set() function fail?
test.c, lines 27-28:
Set* s2;
Set_Create(s2); //.. Here error comes..
In set.c, I have trimmed it down to the meaningful code:
void Set_Create(Set* set){
if(set == NULL){
set = (Set *)malloc(sizeof(Set));
}
set->size = 0;
set->data = -1;
set->next = NULL;
}
What's happening is that both of your calls to Set_Create are overwriting some arbitrary, unpredictable, memory locations. This is a serious bug.
In the case of set1, the arbitrary pointer you have been experiencing seems to happen to point to some place in memory which can be written to. Who knows what data you are clobbering, but your data can survive in that spot for a short duration.
In the case of set2, the arbitrary pointer you are encountering is not a valid memory location for you to modify, so your program crashes.
Change your create_Set like so:
Set* Set_Create() {
Set * set = calloc(1, sizeof(Set));
set->data = -1;
return set;
}
And in test.c:
Set * set1 = Set_Create();

Resources