#include <iostream>
using namespace std;
#include <string.h>
int main()
{
char *sptr;
char *pch;
char *l="hello;world;this;is;a;test;";
cout<<"Starting"<<endl;
for(sptr=l,pch=l;(strchr(pch, ';')?pch = strchr(pch, ';'):pch =
strchr(pch, '\r')) > 0;sptr=++pch) {
*pch=0;
cout<<sptr<<endl;
}
cout<<"Ending"<<endl;
return 1;
}
std::string
int main()
{
char *sptr;
char *pch;
char *l=strdup("hello;world;this;is;a;test;");
sptr=l;
pch=l;
while ( strchr(pch, ';')?(pch=strchr(pch, ';')):(pch=strchr(pch,
'\r')) ) {
*pch=0;
printf("%s\n",sptr);
sptr=++pch;
}
free(l);
return 1;
}
You might want to read comp.lang.c faq 1.32
Or as Nikos pointed it out, use std::string if you're into C++.
> should I really ask the gcc boys?
Probably not.
--
Pierre
xvart wrote:
> char *l=strdup("hello;world;this;is;a;test;");
> free(l);
You've not allocated a memory block to l, so using free is going to cause
undefined behaviour.
TTFN
Paul
--
Sie können mich aufreizen und wirklich heiß machen!
> Hi,
>
> xvart wrote:
>
>> char *l=strdup("hello;world;this;is;a;test;");
>> free(l);
>
> You've not allocated a memory block to l, so using free is going to cause
> undefined behaviour.
strdup() allocates memory with malloc(), so free() is perfectly in
order there.
--
Måns Rullgård
m...@inprovide.com
String constants are stored in the read-only data section, as
modifying them rarely is what you want.
--
Måns Rullgård
m...@inprovide.com
A line like
char *l = "hello;world;this;is;a;test;";
creates a pointer, pointing to a so-called "string literal".
And string literals can't be changed, neither in C or C++.
It doesn't matter where the compiler puts them, all you
need to know is that trying to modify a string literal is
forbidden - it can be in write protected memory. Putting
a 'static' in front of the pointer won't change anything
about it, that only changes some properties of the pointer
variable, not what it's pointing to. What you could put in
front of it instead is 'const', that would enable the com-
piler to complain if you try to change what 'l' is pointing
to. BTW, some implementations don't enforce that literal
strings can't be changed, so people get away with it and
start believing that it would be ok. But they are in for
a bad surprise if they ever try to compile their programs
with a different compiler or on a different system...
On the other hand, with
char *l = sstrdup( "hello;world;this;is;a;test;" );
you get a pointer to a copy of the literal string, where
the copy is now in memory you own (it has freshly been
allocated for you) and you can change that to your hearts
desires, that's why your new version works.
> defined as static and should then be on the heap. I thought static
> meant on the heap, if so what is the difference between a static heap
> allocation and one created with strdup or malloc? should I really ask
You're looking at this the wrong way round. There are
certain rules the language imposes and putting some-
thing on the heap or somewhere else may be a way to
implement these rules the compiler writers chose. But
by using such arguments you are trying to deduce the
rules of the language from the way you imagine it's
implemented in a certain case, and that probably won't
get you very far (even if your assumption should be
correct).
Regards, Jens
--
\ Jens Thoms Toerring ___ j...@toerring.de
\__________________________ http://toerring.de
Could also be opposed to:
char l[] = "hello;world;this;is;a;test;";
That creates an array of chars initialiased in that case to an
array of 28 elements, same as:
char l[] = { 'h', 'e', ... ';', '\0' };
and in which case is read-write.
And you can do:
char k[] = "hello;world;this;is;a;test;";
char *l = k;
--
Stéphane
Måns Rullgård wrote:
>> You've not allocated a memory block to l, so using free is going to cause
>> undefined behaviour.
>
> strdup() allocates memory with malloc(), so free() is perfectly in
> order there.
Um...
strdup returns a pointer to a new string which is a duplicate of the string
passed in. Memory for the string is obtained using malloc.
Nowhere in the code is there a malloc - unless I've misunderstood something,
it's up to the user to do something like
char *m = malloc(300) (say)
m = strdup(foo)
otherwise all that gets returned into m (without the malloc) is going to be
gibberish.
???
There, malloc allocated 300 bytes and returns a pointer to
that which is stored into the m variable. Then you override the
value of m with the pointer returned by strdup. So the original
value returned by malloc is now lost, so you'll have no way to
free it.
> otherwise all that gets returned into m (without the malloc) is going to be
> gibberish.
[...]
No, strdup does allocate enough space to hold a copy of the
input string, copies the input string there an returns a pointer
to the new allocated space.
You can then use free(3) on the value returned by strdup.
--
Stéphane
Source code re-indented for clarity.
% #include <iostream>
%
% using namespace std;
%
% #include <string.h>
%
% int main()
% {
% char *sptr;
% char *pch;
% char *l = "hello;world;this;is;a;test;";
The type of ""hello;world;this;is;a;test;" is not (char *), but (const
char *). This means that the compiler is free to choose to store it
inside a memory region that is mapped as read-only by the time your
main() function runs.
% cout << "Starting" << endl;
%
% for (sptr = l, pch = l;
% (strchr(pch, ';') ?
% pch = strchr(pch, ';') :
% pch = strchr(pch, '\r')) > 0;
% sptr = ++pch)
% {
% *pch = 0;
... and that's why this will fail. You are trying to write, through a
(char *) pointer to a (const char *) region.
% cout << sptr << endl;
% }
% cout << "Ending" << endl;
% return 1;
% }
The fix is simple. Change the type of 'l' from (char *) to:
char l[] = "hello;world;this;is;a;test;";
Then the compiler will create a *mutable* array of characters, with just
enough size to hold the string you used as its initializer, and the
program will stop crashing:
% keramida@kobe:/tmp/foo$ c++ -O2 -Wall -fconserve-space -ggdb foo.cc
% keramida@kobe:/tmp/foo$ ./a.out
% Starting
% l=0xbfbfe8a0, pch=0xbfbfe8a5
% hello
% l=0xbfbfe8a0, pch=0xbfbfe8ab
% world
% l=0xbfbfe8a0, pch=0xbfbfe8b0
% this
% l=0xbfbfe8a0, pch=0xbfbfe8b3
% is
% l=0xbfbfe8a0, pch=0xbfbfe8b5
% a
% l=0xbfbfe8a0, pch=0xbfbfe8ba
% test
% Ending
% keramida@kobe:/tmp/foo$
> char *m = malloc(300) (say)
> m = strdup(foo)
in the above snippet, what's the semantic difference beetwen strdup and
strcpy?
> otherwise all that gets returned into m (without the malloc) is going to be
> gibberish.
DESCRIPTION
The strdup() function returns a pointer to a new string
which is a
duplicate of the string s. Memory for the new string is
obtained with
malloc(3), and can be freed with free(3).
Looks like my man is lying then :-(
How do you get this nice output displaying the addresses? When I run my
g++ with "-ggdb", I get the normal program output. Are these any special
flags that must be set up at the compilation of the compiler?