c string

S

slurper

if i do this

char *mystring="mystring";

later i reassign to mystring like this

mystring="replacewithnewstring";

i'm not a c expert, but i suppose i need to get rid of the dynamically
assigned "mystring"? what should be done according to best practices ?
free(mystring) ?

tx
 
C

Chris Dollin

slurper said:
if i do this

char *mystring="mystring";

later i reassign to mystring like this

mystring="replacewithnewstring";

i'm not a c expert, but i suppose i need to get rid of the dynamically
assigned "mystring"?

There isn't one. Literal strings in C are statically allocated
constants.
what should be done according to best practices ?
Nothing.

free(mystring) ?

That results in Undefined Behaviour. If you're very lucky,
your program will crash.

If you end up in a situation where you're losing the last reference
to a string, and that string may or may not be dynamically allocated,
and you don't know which, backtrack.
 
N

Nicolas Pavlidis

slurper said:
if i do this

char *mystring="mystring";

later i reassign to mystring like this

mystring="replacewithnewstring";

i'm not a c expert, but i suppose i need to get rid of the dynamically
assigned "mystring"? what should be done according to best practices ?
free(mystring) ?

AFAIK this is done my the compiler, onlye if you make the following
thing:

char *mystring = malloc(9 * sizeof(char));
my_string = "mystring";

you'd have to free it, over a call to free, I think.

Kind regrads,
Nicolas
 
J

Joona I Palaste

AFAIK this is done my the compiler, onlye if you make the following
thing:
char *mystring = malloc(9 * sizeof(char));
my_string = "mystring";
you'd have to free it, over a call to free, I think.

No, this is wrong. The assignment my_string = "mystring"; does *NOT*
write the string "mystring" into the memory allocated by the malloc()
call. Rather, it moves the pointer my_string to point at the string
"mystring" (wherever it is stored), ignoring the memory allocated by
malloc() completely.
An attempt to call free(my_string) will cause undefined behaviour.
It is exactly if you attempted to call free("mystring").
Furthermore, all pointers to the memory allocated by malloc() have
gone, so it has become what I call "ghost memory", i.e. memory that is
allocated but impossible to use.
You have to look up strcpy() instead.

--
/-- Joona Palaste ([email protected]) ------------- Finland --------\
\-------------------------------------------------------- rules! --------/
"'So called' means: 'There is a long explanation for this, but I have no
time to explain it here.'"
- JIPsoft
 
S

slurper

Joona said:
No, this is wrong. The assignment my_string = "mystring"; does *NOT*
write the string "mystring" into the memory allocated by the malloc()
call. Rather, it moves the pointer my_string to point at the string
"mystring" (wherever it is stored), ignoring the memory allocated by
malloc() completely.
An attempt to call free(my_string) will cause undefined behaviour.
It is exactly if you attempted to call free("mystring").
Furthermore, all pointers to the memory allocated by malloc() have
gone, so it has become what I call "ghost memory", i.e. memory that is
allocated but impossible to use.
You have to look up strcpy() instead.

tx for answers so far
but i used string literals here, but suppose i use fgets in a loop to
process all lines in a file. i store the lines in a variable (char*
mystring). each line is assigned to the string variable. but what happens
with the strings allocated to it earlear?
for example:
char* mystring;
FILE *stream;
if((stream = fopen ("filename", "r")) != (FILE *)0) {
while((fgets(mystring, 1023, stream)) != (char *)0 ) {
<process each line>
}
} else {
<do fopen error handling>
}
but what happens with the strings i assign to mystring? will i end up with
the whole file except the last line in memory, without references to it?
i don't think C will delete it automatically, because if i say in the loop
char* anotherstring=mystring, i'll end up with two references to the same
string and the compiler can't know the string is still referenced by
another variable.
 
J

Joona I Palaste

tx for answers so far
but i used string literals here, but suppose i use fgets in a loop to
process all lines in a file. i store the lines in a variable (char*
mystring). each line is assigned to the string variable. but what happens
with the strings allocated to it earlear?

If you are indeed assigning the line to a string variable with the =
operator, instead of strcpy() or a similar function, then the previous
value is simply ignored. It is as if your code has:

int a;
a=1;
a=2;

and then you're asking what happens to 1 after the third line.
Now, is it a bad thing that the previous values are ignored? It depends
on how they were initially created. If they were string literals, such
as:

mystring = "Hello world!";

then it's entirely OK, because string literals have program-wide
storage, and the compiler will automatically claim them up when the
program exits. However, if you used malloc() to allocate memory for
them, for example:

mystring = malloc(9); /* no need for sizeof(char) as it is always 1 */

then you get what I called "ghost memory", i.e. a memory leak.
for example:
char* mystring;

You should use malloc() to allocate some memory to store into mystring
here.
FILE *stream;
if((stream = fopen ("filename", "r")) != (FILE *)0) {
while((fgets(mystring, 1023, stream)) != (char *)0 ) {

This fgets() call does *NOT* assign a new value to mystring at all.
The same value - i.e. the same memory location - is reused over and
over again. Only the *contents* of that memory location change.
Therefore it is entirely safe to overwrite the previous line with the
next, without free()ing it. Actually, trying to free() it *would* be
wrong, because then the next fgets() call would try to read data into
unallocated memory.
<process each line>

What does this <process each line> contain? Does it have any statements
of the form

mystring = /* ... */;

? If it doesn't, you're all OK, fine, kosher, hunky-dory. If it *does*,
though, then you have to be careful not to end up with memory leaks.
}
} else {
<do fopen error handling>
}
but what happens with the strings i assign to mystring? will i end up with
the whole file except the last line in memory, without references to it?

By the looks of it, I'd guess not. A definite not if my experience is of
any use. It all depends on what you do in the <process each line> that
you did not show. But if we ignore the <process each line>, then the
above code is completely OK, as long as you remember to actually
allocate some memory for mystring to point to. You should not end up
with the whole file except the last line in memory if my intuition about
your not shown code is of any good. Only the last line should remain in
memory.
i don't think C will delete it automatically, because if i say in the loop
char* anotherstring=mystring, i'll end up with two references to the same
string and the compiler can't know the string is still referenced by
another variable.

This won't matter. If you are indeed using the same value for mystring
over and over again, as I suspect you are, then char *anotherstring =
mystring will simply reuse the same value for anotherstring over and
over again too. Both variables are *always* pointing to the *same*
memory location. You can then later call free(mystring) or
free(anotherstring) - BUT NOT BOTH - to free up the allocated memory.
 
C

Chris Dollin

slurper said:
tx for answers so far
but i used string literals here, but suppose i use fgets in a loop to
process all lines in a file. i store the lines in a variable (char*
mystring). each line is assigned to the string variable. but what happens
with the strings allocated to it earlear?
for example:
char* mystring;
FILE *stream;
if((stream = fopen ("filename", "r")) != (FILE *)0) {
while((fgets(mystring, 1023, stream)) != (char *)0 ) {

`mystring` doesn't point anywhere, so at this point you get Undefined
Behaviour.

In this example you could perfectly happily do

char mystring[1023];

and

fgets( mystring, sizeof mystring, stream )
<process each line>
}
} else {
<do fopen error handling>
}
but what happens with the strings i assign to mystring? will i end up with
the whole file except the last line in memory, without references to it?

No. You didn't allocate any memory, so it won't grow.

If you don't need to keep all the strings you read, allocate `mystring`
once - either as a local array, or with a call to `malloc` (and a matching
`free` when you're done). If you *do* need to keep all the strings you read,
then mallocate per line (and free them all when you're done).
i don't think C will delete it automatically, because if i say in the loop
char* anotherstring=mystring, i'll end up with two references to the same
string and the compiler can't know the string is still referenced by
another variable.

Yes.
 
P

pete

slurper said:
if i do this

char *mystring="mystring";

later i reassign to mystring like this

mystring="replacewithnewstring";

i'm not a c expert, but i suppose i need to get rid of the dynamically
assigned "mystring"? what should be done according to best practices ?
free(mystring) ?

In the context of pointer assignment,
the string literal is converted to a pointer to
an array which resides in memory.
The duration of that array, is until the end of the program.

If you don't use a function like malloc or something similar,
then you're not dealing with dynamic allocation.

Identical string literals may refer to same or different objects.
The exprsssion
("mystring" == "mystring")
may be true in one part of a program
and false in another part of the same program.
 
B

bd

slurper said:
if i do this

char *mystring="mystring";

later i reassign to mystring like this

mystring="replacewithnewstring";
Yep.

i'm not a c expert, but i suppose i need to get rid of the dynamically
assigned "mystring"? what should be done according to best practices ?
free(mystring) ?

No. "mystring" has static storage duration - it cannot be released. It is
not dynamically allocated like memory from malloc() - next time the
function is called (or the scope entered, or whatever) the pointer will be
set to the same string, not a newly allocated one.
 
B

bd

Nicolas said:
AFAIK this is done my the compiler, onlye if you make the following
thing:

char *mystring = malloc(9 * sizeof(char));
my_string = "mystring";

you'd have to free it, over a call to free, I think.

First, mystring and my_string are different identifiers. Second, this is a
memory leak - assigning the address of "mystring" will overwrite the
address of the malloced memory, which can no longer be freed. You probably
meant:
char *mystring = malloc(9); /* sizeof(char) == 1 */
strcpy(mystring, "mystring");
/* do something with mystring */
free(mystring);
 
J

Jim

if((stream = fopen ("filename", "r")) != (FILE *)0) {
while((fgets(mystring, 1023, stream)) != (char *)0 ) {

There's no need to do (FILE *)0 or (char *)0. Either 0 or NULL will
do fine.

Jim
 

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,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top