Why this code is working

J

jammie_linux

Hi,
Please look at the following code. In my opinion, the value of "char
*str" in the main function should not change even after calling the
function "funct" and that's beacuse the "char *str" in the function
funct is local to the function funct and therefore it's value will be
meaningless when the function funct returns. But still the value of
"char *str" in the main function is changing after calling the function
funct. Can anybody help me?


#include <stdio.h>

char *funct()
{
char *str = "This is a local string";
return str;
}

int main(void)
{
char *str;
str = "This is a test";
printf("%s\n",str);
str = funct();
printf("%s\n",str);
return 0;
}
 
P

Paul Lalli

Please look at the following code. In my opinion, the value of "char
*str" in the main function should not change even after calling the
function "funct"

main()'s str is being assigned to the return value of funct()
and that's beacuse the "char *str" in the function
funct is local to the function funct and therefore it's value will be
meaningless when the function funct returns.

No, funct()'s str ceases to exist *after* the call to funct()
completes. The value returned by funct(), on the other hand, is a
perfectly valid value.
But still the value of
"char *str" in the main function is changing after calling the function
funct.

Of course it is. You're assigning it to a new value. It changes just
like any other assignment statement would make it change.
#include <stdio.h>

char *funct()
{
char *str = "This is a local string";
return str;

You are returning the *value* that str holds at this point in the code.
That is, funct() returns the string "This is a local string"

"Here", funct() has ended, and so funct()'s str no longer exists. But
the value has already been returned.
int main(void)
{
char *str;
str = "This is a test";

Here you assign a value to main()'s str
printf("%s\n",str);
str = funct();

Here you call funct(), and assign funct()'s return value to main's
str(). This has precisely the same side effect as:
str = "This is a local string";
printf("%s\n",str);
return 0;
}

It may be the fact that main()'s str and funct()'s str variables happen
to have the same name, but other otherwise completely unrelated, that
is confusing you.

Paul Lalli
 
J

jammie_linux

But when a function returns, the compiler reclaims all the memory
assigend to the local variables. By this theory, isn't it possible that
the memory where the string "This is local to the function" was
stored, would also be reclaimed. In that case, the main's function str
will be pointing at a totally meaningless position.
 
S

Simon Biber

But when a function returns, the compiler reclaims all the memory
assigend to the local variables. By this theory, isn't it possible that
the memory where the string "This is local to the function" was
stored, would also be reclaimed. In that case, the main's function str
will be pointing at a totally meaningless position.

No, because the string "this is local to the function" is *not* local to
the function. String literals always have static duration, no matter
where you declare them. The string literal continues to exist even after
the function returns.

If you had instead used the string literal as an initialiser for a local
array, then it would have returned an invalid pointer as you seem to expect.

Compare the following functions:

char *funct1()
{
char *str = "This is a string literal with static duration.";
return str;
}

char *funct2()
{
char str[] = "But this one is used to initialise a local array.";
return str;
}

The [] in funct2 make all the difference. Funct1 returns a valid
pointer, but funct2 returns an invalid pointer.
 
J

jammie_linux

Simon wrote :
"String literals always have static duration, no matter
where you declare them."

Is the same is also true when you allocate memory via malloc and other
related function like in the case below:
Also, in this code the getnode() is not returning anything explicitly(
even though it should), still it is implicitly returning the value of
node * q defined locally in it. Is this what the standard says or is
happening at the mercy of the compiler?

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
int data;
struct node * next;
}node;

node * getnode()
{
node * q = malloc(sizeof(node));
if(q == NULL)
{
printf("Insufficient memory\n");
exit(1);
}

q->data = 9;
q->next = NULL;


}

void display(node *q)
{
if(q == NULL)
{
printf("q is NULL in display\n");
exit(1);
}
printf("%d %p\n",q->data, (void*)q->next);
return;
}


int main(void)
{
node * q;

q = getnode();
display(q);
return 0 ;
}
 
S

Simon Biber

Simon wrote :
"String literals always have static duration, no matter
where you declare them."

Is the same is also true when you allocate memory via malloc and other
related function

Similar. The memory block allocated by the 'malloc', 'calloc' or
'realloc' functions will remain valid until the base address of the
block is passed to the 'free' function. It doesn't matter whether the
pointer gets passed to or from functions.
> like in the case below:
Also, in this code the getnode() is not returning anything explicitly(
even though it should), still it is implicitly returning the value of
node * q defined locally in it.

It's not implicitly returning anything. The code is wrong, and will not
compile.
Is this what the standard says or is
happening at the mercy of the compiler?

After you fix the errors below, the code is valid according to the
standard. It should compile and run on all C compilers.
#include <stdio.h>
#include <stdlib.h>

typedef struct node {
int data;
struct node * next;
}node;

node * getnode()
{
node * q = malloc(sizeof(node));
if(q == NULL)
{
printf("Insufficient memory\n");
exit(1);

The exit code 1 is not defined by the C standard, and could have
unintended effects. If you want to indicate that the program failed, you
should write
exit(EXIT_FAILURE);
}

q->data = 9;
q->next = NULL;

You should have the line
return q;
here.
}

void display(node *q)
{
if(q == NULL)
{
printf("q is NULL in display\n");
exit(1);
}
printf("%d %p\n",q->data, (void*)q->next);
return;
}


int main(void)
{
node * q;

q = getnode();
display(q);

You should have the line
free(q);
here.
return 0 ;
}

Once you correct the errors shown above, this code is fine.
 
K

Keith Thompson

But when a function returns, the compiler reclaims all the memory
assigend to the local variables. By this theory, isn't it possible that
the memory where the string "This is local to the function" was
stored, would also be reclaimed. In that case, the main's function str
will be pointing at a totally meaningless position.

Don't assume your readers can see the article to which you're
replying. You need to provide some context in the form of properly
attributed quotations from the parent article (not necessarily the
whole thing, just what's relevant to your reply). See nearly any
followup in this newsgroup for an example.

Google Groups makes this gratutiously difficult. Please follow these
instructions (which have been posted here over 1000 times), and
*please* complain to Google about their broken interface, which
they've persistently refused to fix.

If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers.
 
J

Jordan Abel

But when a function returns, the compiler reclaims all the memory
assigend to the local variables. By this theory, isn't it possible that
the memory where the string "This is local to the function" was
stored, would also be reclaimed.

No, the string "This is local to the function" in this situation is
in static storage, because it is a string literal not being used to
initialize an array.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top