473,785 Members | 2,669 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Crazy stuff

If I have this(please bear with me - this is a case of a former java
guy going back to C ;-)

int main () {
char *tokconvert(cha r*);
char str[] = "dot.delimited. str";
char *result;

result = tokconvert(str) ;
return 0;
}

char *tokconvert(cha r *strToConvert) {

char *token;
char *tokDelim =",.";

token=strtok(st rToConvert, tokDelim);

while(token != NULL) {
printf("Token -> %s \n", token);
token=strtok(NU LL, tokDelim);
}
}

the thing compiles and runs fine, however if I declare char *str =
"dot.delimited. str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?

more craziness: if I declare/initialise

char *str;
str = strdup("dot.del imited.str)

inside tokconvert (instead of main) and pass that to strtok - it runs
fine!!

any thoughts are most welcome..

chumbo.

P.S.
btw this is on FreeBSD 5.1.2 (using gcc 3.3.3)
Nov 14 '05 #1
32 1985
Chumbo wrote:
the thing compiles and runs fine, however if I declare char *str =
"dot.delimited. str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?


char *str = "blah";

is allowed to be placed in read-only memory. The data cannot be modified.

char str[], however, must be placed in memory modifiable by you (i.e. the
stack).

--
Jason Whitehurst
Nov 14 '05 #2
Jason Whitehurst wrote:
is allowed to be placed in read-only memory. The data cannot be
modified.


Err, and in case you don't know, strtok(3) modifies the input string. Thus,
your problem.

--
Jason Whitehurst
Nov 14 '05 #3
In article <50************ **************@ posting.google. com>,
Chumbo <ch*********@ho tmail.com> wrote:
If I have this(please bear with me - this is a case of a former java
guy going back to C ;-)

int main () {
char *tokconvert(cha r*);
It will confuse people less if you put function prototypes at file scope
instead of inside functions. (In this particular case, you can avoid
needing the prototype altogether by putting tokconvert before main(),
but that's not always possible or reasonable.)
char str[] = "dot.delimited. str";
This allocates an array of char and populates it with the characters
in the string "dot.delimited. str" (including the terminating '\0').
The array is in the automatic-allocation space (we can call this "the
stack", but we prefer not to, because the function-invocation stack that
it exists in is not the same stack as the "processor' s stack segment"
stack (which need not even exist) that people typically assume we're
talking about), and therefore that we can do pretty much whatever we
want with it (the relevant bit of that here is that we can write to it)
until the function returns.
char *result;

result = tokconvert(str) ;
When you pass str (an array) to a function (or do most other things with
it, notable exceptions being applying & or sizeof to it), the array name
decays to a pointer to the array's first element. In this case, this
is exactly what you want - a pointer to the first character of the string.
return 0;
}

char *tokconvert(cha r *strToConvert) {

char *token;
char *tokDelim =",.";

token=strtok(st rToConvert, tokDelim);

while(token != NULL) {
printf("Token -> %s \n", token);
token=strtok(NU LL, tokDelim);
}
You're not returning anything here. Your compiler should have warned
you about that.
(I'm not sure what you'd've wanted to return; possibly this is a leftover
from doing something with the tokens other than just printing them?)
}
the thing compiles and runs fine, however if I declare char *str =
"dot.delimited .str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?
When you say `char *str="a string literal"', the string literal (like
any other string literal in the program[1]) refers to an anonymous
not-const-but-not-writeable array of characters containing the string.
In English, that means you're allowed to point a pointer that you're
allowed to write through at it (remember, arrays decay to pointers),
but you're not actually allowed to write to it.

So, you have a pointer pointing at a string literal that you're not
allowed to write to... and then you try to write to it (indirectly,
by passing it to strtok, which writes to its first argument). That's
what's causing your problem. The solution is to Don't Do That, Then:
Allocate writeable space for the string you give strtok as its first
argument, either as an automatic variable (like in your code above)
or as dynamically allocated memory (f'rexample, memory from strdup as
below), and put the string into that.

more craziness: if I declare/initialise

char *str;
str = strdup("dot.del imited.str)

inside tokconvert (instead of main) and pass that to strtok - it runs
fine!!
Note that strdup is a unixism and not part of the C language.[2]

What strdup does is allocate (with malloc) enough memory to hold the
string you give it, and copy the string into that memory, and return a
pointer to the copy of the string. This memory is writeable, so giving
strdup a pointer to it isn't a problem, for the same reason that giving
it a pointer to the automatically allocated array isn't a problem.

P.S.
btw this is on FreeBSD 5.1.2 (using gcc 3.3.3)


If I'd needed to know that, then your question would have been
inappropriate for comp.lang.c and would have been better off asked in
a FreeBSD or GCC newsgroup.

But given that you're using GCC: If you'd compiled with:
gcc -W -Wall -ansi -pedantic -O myprog.c
then GCC would have warned you about failing to return a value from
tokconvert, along with a bunch of other warnings about things that you
typically don't want to do. This makes debugging some problems a lot
easier - they go away when the compiler stops warning you about them.
dave

[1] In language-lawyer-ese, the string in the array initialization
`char buf[]="a string"' is an initializer, not a string literal;
this is, as far as I know, the only place you can have a string in
the source code that doesn't represent an anonymous array of char.

[2] It's in the implementation' s namespace, though, which means you're
not allowed to define it yourself. The solution in comp.lang.c is
to use my_strdup, which can portably be defined and have the same
behavior as the unix strdup; the usual solution outside comp.lang.c
is to use the library's strdup if it exists, and otherwise to apply
knowledge beyond that found in the language definition to establish
that the programmer is allowed to define a function by that name on
that implementation and do so.

--
Dave Vandervies dj******@csclub .uwaterloo.ca
Well, it's rare. The usual reaction to "let me just show you the bit..."
is "Rich! Rich! We ***believe*** you, okay?!?!?!?!?!"
--Richard Heathfield in comp.lang.c
Nov 14 '05 #4

"Chumbo" <ch*********@ho tmail.com> wrote

token=strtok(st rToConvert, tokDelim);
the thing compiles and runs fine, however if I declare char *str =
"dot.delimited. str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?

strtok()s first argument is a char *, and is overwritten to produce the
token (yes, this is a terrible way of doing things, as an ex-Java man you
probably expect something like the Java string tokeniser).
char *str = "My string"; creates a constant string in read-only memory.
char str[] = "My string"; creates a string in read-write memory.

The result of passing a constant string to strtok is undefined.
Nov 14 '05 #5
so I am a little confused...how does the compiler actually go about creating
read-only memory and read-write memory? Hows the distinction based?

"Malcolm" <ma*****@55bank .freeserve.co.u k> wrote in message
news:cm******** **@newsg2.svr.p ol.co.uk...

"Chumbo" <ch*********@ho tmail.com> wrote

token=strtok(st rToConvert, tokDelim);
the thing compiles and runs fine, however if I declare char *str =
"dot.delimited. str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?

strtok()s first argument is a char *, and is overwritten to produce the
token (yes, this is a terrible way of doing things, as an ex-Java man you
probably expect something like the Java string tokeniser).
char *str = "My string"; creates a constant string in read-only memory.
char str[] = "My string"; creates a string in read-write memory.

The result of passing a constant string to strtok is undefined.

Nov 14 '05 #6
"Siddharth Taneja" <ta****@usc.edu > wrote in message
news:cm******** **@gist.usc.edu ...
so I am a little confused...how does the compiler actually go about creating read-only memory and read-write memory?
However it wants.
Hows the distinction based?


Depends upon the compiler. Each one does things its own
way. If you want to know how yours does it, consult
its support resources.

BTW please don't top-post. Thanks.

-Mike

Nov 14 '05 #7

"Siddharth Taneja" <ta****@usc.edu > wrote

so I am a little confused...how does the compiler actually go about creating read-only memory and read-write memory? Hows the distinction based?

This one of the problems of C.

On a desktop system, typically the whole program will be loaded into
physical RAM. On many systems, pages may be marked as "read only" or
"executable only", so attempts to write to those pages cause runtime faults.
However on other systems, such as older microcomputers, there was no
mechanism for doing this, so a write to a constant area of memory would
change the contents and cause mysterious malfunctions.

On embedded systems, it is quite common for the executable code and the
constant data to be held in physical ROM. Obviously any attempt to write to
this will not possibly alter the contents.
Nov 14 '05 #8
On 6 Nov 2004 21:22:16 -0800, ch*********@hot mail.com (Chumbo) wrote:
If I have this(please bear with me - this is a case of a former java
guy going back to C ;-)

int main () {
char *tokconvert(cha r*);
char str[] = "dot.delimited. str";
char *result;

result = tokconvert(str) ;
return 0;
}

char *tokconvert(cha r *strToConvert) {

char *token;
char *tokDelim =",.";
This is an example of where using static might an impact on
performance if the function were called often.

token=strtok(st rToConvert, tokDelim);

while(token != NULL) {
printf("Token -> %s \n", token);
token=strtok(NU LL, tokDelim);
}
}
How can this function compile fine? It is required to return a
pointer to char yet there is no return statement in the function at
all.

the thing compiles and runs fine, however if I declare char *str =
"dot.delimited .str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?

more craziness: if I declare/initialise

char *str;
str = strdup("dot.del imited.str)
This is not a standard function.

inside tokconvert (instead of main) and pass that to strtok - it runs
fine!!


Others have explained why.
<<Remove the del for email>>
Nov 14 '05 #9
On Sun, 7 Nov 2004 09:13:08 -0000, "Malcolm"
<ma*****@55bank .freeserve.co.u k> wrote in comp.lang.c:

"Chumbo" <ch*********@ho tmail.com> wrote

token=strtok(st rToConvert, tokDelim);
the thing compiles and runs fine, however if I declare char *str =
"dot.delimited. str" (instead of char str[] = "dot.delimited. str") the
whole thing falls on its ass real bad (bus error) - strtok is defined
as char *strtok(char *, const char *) - what's going on?
strtok()s first argument is a char *, and is overwritten to produce the
token (yes, this is a terrible way of doing things, as an ex-Java man you
probably expect something like the Java string tokeniser).


So far, so good.
char *str = "My string"; creates a constant string in read-only memory.
The line above is completely wrong. "My string" is a string literal,
and the C standard states that it has the type array of char.
Specifically NOT array of const char. So it is not a constant string.
Furthermore, C does not define any such thing as "read-only memory".
char str[] = "My string"; creates a string in read-write memory.
The line above creates an array of chars that may be modified,
provided that its bounds are not exceeded. C does not define any such
thing as "read-write memory".
The result of passing a constant string to strtok is undefined.


That is true, but does not apply here. The result of attempting to
modify a string literal is undefined behavior. This is true not
because the type of the string literal is array of const char, but
because the C standard specifically states that it is so.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.l earn.c-c++
http://www.contrib.andrew.cmu.edu/~a...FAQ-acllc.html
Nov 14 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
1670
by: Tom Schmitt | last post by:
Hi everybody. For a long time now, I've been searching for a good, fast, reliable CMS. Most of the stuff out there (like phpnuke) is too fancy and overloaded for what I need: - more than one Menu-Layer... submenus and all - MySQL-support - configurable templates - custom input templates (not a must) That's all I need. Do you have any suggestions on what to use/try out?
7
3383
by: Oliver Andrich | last post by:
Hi everybody, I have to write a little skript, that reads some nasty xml formated files. "Nasty xml formated" means, we have a xml like syntax, no dtd, use html entities without declaration and so on. A task as I like it. My task looks like that... 1. read the data from the file. 2. get rid of the html entities 3. parse the stuff to extract the content of two tags.
11
3351
by: doltharz | last post by:
Please Help me i'm doing something i though was to be REALLY EASY but it drives me crazy The complete code is at the end of the email (i mean newsgroup article), i always use Option Explicit and Response.Expires=-1,
4
1800
by: Teknowbabble | last post by:
Hi All... Ive done several simple web pages, no biggy! Is there any way to layout a Table with lets say 3 columns and have the contents of those columns not have to fit the rigid row column standard of setting up tables. Basically all I want to do is fill up column one, then column 2, and then column 3. Each column has its spacing.
38
4597
by: Kai Jaeger | last post by:
I am playing with setting font sizes in CSS using em as unit of measurement. All seems to be fine. Even Netscape Navigator shows the characters very similar to IE, what is not the kind if px is used! But! when selecting the "Larger" or "Smaller" command from the menubar in IE, font sizes increases from normal (1em) to, say, 6em or so _in the first step_!!! In the next step it seems to be 20em or say. Choosing "Smaller" makes the text...
9
2341
by: rbronson1976 | last post by:
Hello all, I have a very strange situation -- I have a page that validates (using http://validator.w3.org/) as "XHTML 1.0 Strict" just fine. This page uses this DOCTYPE: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> When I change the DOCTYPE to (what should be the equivalent):
1
4600
by: Bruce W.1 | last post by:
I want to put a live connection in a web page to periodically updated data. When the data changes, the server notifys the client and gives the new data. The client does not regularly refresh the page. The client responds to server-side events only. The screen display changes without any user interaction. An application like this might be a chat, stock ticker, or data inventory. Sofar as I can tell nothing in the .NET framework can...
5
1715
by: Pupeno | last post by:
Hello, I am experiencing a weird behavior that is driving me crazy. I have module called Sensors containing, among other things: class Manager: def getStatus(self): print "getStatus(self=%s)" % self return {"a": "b", "c": "d"} and then I have another module called SensorSingleton that emulates the
3
1770
by: squash | last post by:
I have spent two hours trying to make sense of this script, called crazy.php. The output should be nothing because $cookie_password is nowhere defined in this script, correct? But it actually outputs the value that other scripts i have running set it to. Why should crazy.php care what other scripts are running that use that variable name?? <?php crazy();
2
3631
by: kheitmann | last post by:
OK, so I have a blog. I downloaded the "theme" from somewhere and have edited a few areas to suit my needs. There are different font themes within the page theme. Long story short, my "Text Posts" are supposed to be in the font: Georgia, but they are showing up in "Times New Roman"...blah! I can't find anything wrong in the code, but who am I trying to fool? I know nothing about this stuff. The code is below. The parts that I *think*...
0
9645
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10324
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10090
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9949
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7499
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6739
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5380
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3645
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.