Thread: memory and strtok function!!

  1. #1
    Registered User
    Join Date
    Apr 2008
    Posts
    103

    memory and strtok function!!

    Hi!
    the program below is supposed to accept a sentence, and then print out the words in that sentence. the program works fine, but in the end it gives me an error specifying that memory couldn't be read.
    do I dismanage my memory here?
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(int arg, char* argv[]){
                 char *sentence,words[5][200];
                 int i = 0;
                 sentence = (char*) malloc(sizeof(char) * 200);
                 printf("Please enter your sentence(s):\n");
                 gets(sentence);
                 strcpy(words[i] , strtok(sentence," "));
                 while (words[i]){
                       puts(words[i]);
                       i++;
                       strcpy(words[i] , strtok(NULL," "));
                       }
                 system("PAUSE");
                 return 0;

  2. #2
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    Code:
    while (words[i]){
    words[i] is an array of 200 characters, it always has a valid address as long as the indicies are between 0 and 4 (inclusive) so using that in the conditional part of the loop is wrong. Also, once "i" gets incremented past 4 (if there are more than 4 words), you'll likely get some kind of error since words[5] is an invalid index.

    Also, gets is dangerous, it does nothing to prevent the user from entering in more characters than the you've got set up to receive. fgets is a better choice since you can specify a maximum number of characters to accept. There's also no need to have sentence be a pointer instead of just a regular array.
    Last edited by hk_mp5kpdw; 05-24-2008 at 08:25 PM.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  3. #3
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I see a lot of suspect code here. It's completely broken. I'd start over.

    Code:
    gets(sentence);
    strcpy(words[i] , strtok(sentence," "));
    The problem with statements like these is that it is all too easy to type too much text and write off the end of the array, which, to borrow your phrasing "mismanages memory." This evokes undefined behavior.

    Also, strcpy gives no guarantee it will handle NULL safely, a pointer strtok can return on failure.

    If we give the user the benefit of the doubt and assume he's cooperative, then you definitely run into an issue here:
    Code:
    while (words[i]){
    When I ran your program through with my debugger, this was where execution broke. This condition doesn't work: it implicitly compares a pointer to zero. Bounds checking for i is the correct way to make sure you fill in all the words you have space for. Do bounds checking for all your arrays from now on so that you don't waltz off the end of them, or execute code more times than you should. If you do bounds checking you should have a completely easier time with arrays.

  4. #4
    Registered User
    Join Date
    Apr 2008
    Posts
    103
    Well, we didn't cover fgets so far in class, and also it's my first time using strtok..
    The problem is that I want to sotre every word of the sentence in a string, that why I used that TWO dimensional array.
    Ok but why this is not working
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    int main(int arg, char* argv[]){
                 char *sentence,words[200];
                 int i = 0;
                 sentence = (char*) malloc(sizeof(char) * 200);
                 printf("Please enter your sentence(s):\n");
                 gets(sentence);
                 strcpy(words , strtok(sentence," "));
                 while (words){
                       puts(words);
                       strcpy(words,strtok(NULL," "));
                       }
                 system("PAUSE");
                 return 0;
    compared to the code in this webpage.
    http://www.cplusplus.com/reference/c...ng/strtok.html

  5. #5
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    It's the same as before. You can't control the loop with the words pointer because it doesn't make sense to do it that way in this program or the snippet you just posted.

    I believe your snippet should be:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
       char sentence[200];
       char * token;
       
       printf("Enter a sentence\n");
       gets(sentence); 
       /** throwing caution to the wind... **/
       
       token = strtok(sentence, " ");
       while (token != NULL) {
          puts(token);
          token = strtok(NULL, " ");
       }
       return 0;
    }
    A proper way to do this would be to look at strtok's return value, and if it's something other than NULL, store it or print it. But you take it for granted that strtok will always return a word you can copy or that anything you do in this loop will have an effect on word so that the loop will break on time.

    It's really not that difficult, you've just got to be sure your loops have proper test conditions.
    For example, in your earlier program, there might be more words in the sentence than there are spaces. Or strtok might return NULL so you have no substring to copy. Without handling either of these, you cannot fix your earlier program.

  6. #6
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Even if you haven't covered fgets, I'm just going to put it in there nevertheless:
    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
       char sentence[200];
       char * token;
       
       printf("Enter a sentence\n");
       fgets(sentence, sizeof(sentence), stdin); 
       /** throwing caution to the wind... **/
       
       token = strtok(sentence, " ");
       while (token != NULL) {
          puts(token);
          token = strtok(NULL, " ");
       }
       return 0;
    }
    Gets is incredibly dangerous and should never ever be used, no matter what.
    What some also failed to mention is that buffer overruns are a security issue among others: http://cpwiki.sourceforge.net/Buffer_overrun
    And C is big pitfall when it comes to security: http://www.cse.scu.edu/~tschwarz/COE...es/Strings.ppt

    Show that presentation to your teacher, maybe.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Any Memory Leak Here
    By akm3 in forum C Programming
    Replies: 8
    Last Post: 03-15-2009, 05:03 PM
  2. 20q game problems
    By Nexus-ZERO in forum C Programming
    Replies: 24
    Last Post: 12-17-2008, 05:48 PM
  3. Replies: 8
    Last Post: 03-10-2008, 11:57 AM
  4. Dynamic memory problem
    By *Tom* in forum C Programming
    Replies: 8
    Last Post: 09-11-2006, 10:50 AM
  5. How can I free what strtok returns?
    By registering in forum C Programming
    Replies: 3
    Last Post: 06-24-2003, 04:56 PM