doubt regarding pointer assignment

S

somenath

Hi All,

I have a doubt regarding the pointer assignment . Please have a look
at the following program .

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 10
#define SAFE_FREE(t) if(t)\
{\
free(t);\
t=NULL;\
}\

int main(void)
{

char *s = malloc(NAMESIZE * sizeof *s);
s = "somenath";
*(s+1)= 'b';/* will it show undefine behavior ??*/
puts(s);
SAFE_FREE(s);
return 0;


}

My question is
1) is the assignment "s = "somenath"; " copy the string to s?
2) is the behavior of *(s+1)= 'b' is defined ?
Currently I am getting the output as

sbmenath


Regards,
Somenath
 
M

Marjancek

Hi All,

I have a doubt regarding the pointer assignment . Please have a look
at the following program .

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 10
#define SAFE_FREE(t) if(t)\
{\
free(t);\
t=NULL;\
}\

int main(void)
{

char *s = malloc(NAMESIZE * sizeof *s);
s = "somenath";
*(s+1)= 'b';/* will it show undefine behavior ??*/
puts(s);
SAFE_FREE(s);
return 0;

}

My question is
1) is the assignment "s = "somenath"; " copy the string to s?
2) is the behavior of *(s+1)= 'b' is defined ?
Currently I am getting the output as

sbmenath

Regards,
Somenath

You are doing smething really nasty.

The line
s = "somenath"
actually replaces the pointer to the allocated memory references by
's' with the pointer to a static method variable.
Then you are modifying static data!

You should have done
strcpy(s, "somenath);

And the behaviour will be defined.

Mariano.
 
R

Richard Heathfield

somenath said:
Hi All,

I have a doubt regarding the pointer assignment .

More idiomatically, "I have a question regarding pointer assignment."
(Strike two.)
Please have a look
at the following program .

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 10
#define SAFE_FREE(t) if(t)\
{\
free(t);\
t=NULL;\
}\

What makes you think this macro justifies its name?
int main(void)
{

char *s = malloc(NAMESIZE * sizeof *s);

That's fine.
s = "somenath";

That isn't. You just leaked memory. What you intended to do was to copy
the string literal "somenath" into the buffer allocated by malloc,
whose first byte's address is stored in s. To do this, #include
*(s+1)= 'b';/* will it show undefine behavior ??*/

Yes as your code stands, but not if you correct it as I outlined above.
puts(s);
SAFE_FREE(s);
return 0;


}

My question is
1) is the assignment "s = "somenath"; " copy the string to s?

No. The string literal "somenath" resides at some address or other, and
the assignment simply stores that address in s (which necessarily means
that s can no longer store the address of the block that may have been
allocated by malloc). No copying of the string has occurred.
2) is the behavior of *(s+1)= 'b' is defined ?

Not in your code as written.
Currently I am getting the output as

sbmenath

One of the possible outcomes of undefined behaviour is "what you hoped
would happen", but it is by no means the only one.
 
C

Chris Dollin

somenath said:
I have a doubt regarding the pointer assignment . Please have a look
at the following program .

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 10
#define SAFE_FREE(t) if(t)\
{\
free(t);\
t=NULL;\
}\

Horrible horrible. If you /are/ going to tempt fate this way,
what's wrong with:

#define SAFE_FREE(t) (free( t ), t = NULL)

which at least is short and doesn't lead you into a semicolon
trap.

[There are at least two ways which make this a fate-tempting
macro, one more subtle than the other.]
int main(void)
{

char *s = malloc(NAMESIZE * sizeof *s);
s = "somenath";

Oops. You've just lost your reference to the allocated store.

Perhaps you meant

strcpy( s, "somenath" );

?
*(s+1)= 'b';/* will it show undefine behavior ??*/

[Why not write this as

s[1] = 'b';
?]

As you have written it, yes, because you're trying to change
the second character of the string literal, and this is Not
Allowed.
puts(s);
SAFE_FREE(s);

That's the semicolon trap: there's an empty statement between
the `)` and the `;`. Think about what would happen if the
SAFE_FREE was the then-part of an `if` with an `else`.
return 0;
My question is
1) is the assignment "s = "somenath"; " copy the string to s?
No.

2) is the behavior of *(s+1)= 'b' is defined ?

Not as written.
Currently I am getting the output as

sbmenath

It appears your implementation doesn't take advantage of its permission
to store string literals in read-only memory.
 
R

Richard

Richard Heathfield said:
somenath said:


More idiomatically, "I have a question regarding pointer assignment."
(Strike two.)

1


What makes you think this macro justifies its name?

2

So two answers. 2 picky, trite little comments with no correction and/or
actual advice. This is the kind of pedantry and rudeness so often
mentioned in relation to this group. If you are going to pick on such
issues then have the god given good grace to explain why you are so
pleased with yourself. The OP might learn something.

That's fine.


That isn't. You just leaked memory. What you intended to do was to copy
the string literal "somenath" into the buffer allocated by malloc,
whose first byte's address is stored in s. To do this, #include


Yes as your code stands, but not if you correct it as I outlined
above.

RH means something like

strcpy(s,"somenath");
No. The string literal "somenath" resides at some address or other, and
the assignment simply stores that address in s (which necessarily means
that s can no longer store the address of the block that may have been
allocated by malloc). No copying of the string has occurred.


Not in your code as written.

Yes is if s points to a valid string. Which it does before you
mistakenly set it to point to "somenath".
One of the possible outcomes of undefined behaviour is "what you hoped
would happen", but it is by no means the only one.

You output is what would be expect in 99.99% of cases and is probably
what you expected it to be. It is however "undefined" in that you did
not store the 'b' in your malloced memory, rather in the "static" string
area used to store "somenath".
 
S

somenath

at the following program .
What makes you think this macro justifies its name?
Thanks for the information. By using this macro I wanted to avoid the
repetation of following steps
1)Before freeing pointer check if it is NULL.
2)If not NULL free it .
3)After freeing assign the pointer to NULL.
I think i am achieving these by the macro SAFE_FREE.
Please provide your inputs if it is not doing so. or what i am doing
wrong or how it can cause problem or it can be improved .

Thanks

Regards,
Somenath
 
R

Richard Heathfield

somenath said:
Thanks for the information. By using this macro I wanted to avoid the
repetation of following steps
1)Before freeing pointer check if it is NULL.

Unnecessary. free(NULL) is legal, and does nothing.
2)If not NULL free it .
3)After freeing assign the pointer to NULL.

I don't think this buys you a great deal - not enough to justify the use
of a macro, at any rate. Nevertheless, it's not actually wrong, as
such. But beware - it's not as useful as you might think. Consider the
case where a pointer is passed to a function and, in *some*
circumstances, you pass it to your SAFE_FREE macro. It is tempting to
think that, on return from that function, your pointer will be set to
NULL if the memory was freed (because you used SAFE_FREE) - but in fact
it won't be (because C is a pass-by-value language).

Use it if you must, but be very, very careful with it.
 
C

CBFalconer

somenath said:
I have a doubt regarding the pointer assignment . Please have a
look at the following program .

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 10
#define SAFE_FREE(t) if(t)\
{\
free(t);\
t=NULL;\
}\

Silly macro. "free(NULL)" is treated as a NOP. See the standard.
int main(void) {
char *s = malloc(NAMESIZE * sizeof *s);
s = "somenath";

destroying s value and making a memory leak.
*(s+1)= 'b';/* will it show undefine behavior ??*/

and now pointing to a non-modifiable char const. Boom. Undefined
behaviour.
puts(s);
SAFE_FREE(s);
return 0;
}

My question is
1) is the assignment "s = "somenath"; " copy the string to s?
2) is the behavior of *(s+1)= 'b' is defined ?

You are asking the wrong questions. But the answers are no, yes.
Note that s can't hold a string, only a pointer.
 
K

Keith Thompson

Richard said:
Richard Heathfield said:
somenath said: [...]
2) is the behavior of *(s+1)= 'b' is defined ?

Not in your code as written.

Yes is if s points to a valid string. Which it does before you
mistakenly set it to point to "somenath".
One of the possible outcomes of undefined behaviour is "what you hoped
would happen", but it is by no means the only one.

You output is what would be expect in 99.99% of cases and is probably
what you expected it to be. It is however "undefined" in that you did
not store the 'b' in your malloced memory, rather in the "static" string
area used to store "somenath".

Really? When I compiled and ran the program, I got the output I
expected, namely:

Segmentation fault (core dumped)

String literals are very commonly stored in read-only memory (not
necessarily physically read-only except on embedded systems, but in a
memory segment that's protected from writing by the operating system).

The output the OP got, "sbmenath", is not surprising (apparently his
system doesn't write-protect string literals), but some kind of
program crash is also very likely.
 
P

pete

somenath said:
Hi All,

I have a doubt regarding the pointer assignment . Please have a look
at the following program .

#include<stdio.h>
#include<stdlib.h>
#define NAMESIZE 10
#define SAFE_FREE(t) if(t)\
{\
free(t);\
t=NULL;\
}\

int main(void)
{

char *s = malloc(NAMESIZE * sizeof *s);
s = "somenath";
*(s+1)= 'b';/* will it show undefine behavior ??*/
puts(s);
SAFE_FREE(s);
return 0;

}

My question is
1) is the assignment "s = "somenath"; " copy the string to s?
No.

2) is the behavior of *(s+1)= 'b' is defined ?
No.

Currently I am getting the output as

sbmenath

Sheer luck.

/* BEGIN new.c */

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

#define STRING "somenath"

int main(void)
{
char *s = malloc(sizeof STRING);

if (s == NULL) {
puts("s == NULL");
exit(EXIT_FAILURE);
}
strcpy(s, STRING);
s[1]= 'b';
puts(s);
free(s);
s = NULL;
return 0;
}

/* END new.c */
 

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

Forum statistics

Threads
474,159
Messages
2,570,888
Members
47,420
Latest member
ZitaVos505

Latest Threads

Top