Help with char*
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 10 of 10

Thread: Help with char*

  1. #1
    Join Date
    Sep 2009
    Posts
    11

    Help with char*

    Please can some one help me point out what's wrong with the code below. There's an intermittent error when trying to push_back into the vector.

    I need to use char* because an API I'll be using will be expecting char*

    Code:
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
    
        char* s = "The quick brown fox jumps over the lazy dog The quick brown's fox jumps over's the lazy dog. The quick brown fox jumps over the lazy dog The quick brown fox jumps over the lazy dog";
        vector<char*> textarray;
    
        char* buffer;
        int firstpos = 0;
        int bsize = 0;
    
        for (int i = 0; i < strlen(s); i++)
        {
            if (s[i] == ' ')
            {
                bsize = i - firstpos + 1;
    
                if (bsize > 0)
                {
                    buffer = new char[bsize];
                    strncpy(buffer, &s[firstpos], bsize);
                    buffer[bsize] = NULL;
                    cout << "bsize: " << bsize << " " << strlen(buffer) << " (" << buffer << ")" << endl;
                    //delete [] buffer;
                    textarray.push_back(buffer);
                }
    
                firstpos = i + 1;
            }
        }
    
        for (int i=0; i < textarray.size(); i++)
        {
            cout << "deleted : " << textarray[i] << endl;
            delete [] textarray[i];
        }
    
        return 0;
    }
    ps. I'm using latest CodeBlocks with mingw
    Last edited by cic.lemur; September 25th, 2009 at 11:25 PM. Reason: added info

  2. #2
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Fairfax, VA
    Posts
    10,888

    Re: Help with char*

    Quote Originally Posted by cic.lemur View Post
    I need to use char* because an API I'll be using will be expecting char*
    You can get one from a nonempty vector<char> vec by taking &vec[0].

    For that matter, if a const char* is good enough, then you can get one even more easily from a std::string using the .c_str() member.

    The immediate problem is here:
    Code:
           
                    buffer = new char[bsize];
                    strncpy(buffer, &s[firstpos], bsize);
                    buffer[bsize] = NULL;
    Since you've allocated bsize chars, therefore the maximum valid index is bsize-1. You're writing a NULL past the end of allocated memory.
    Last edited by Lindley; September 25th, 2009 at 11:31 PM.

  3. #3
    Join Date
    Apr 1999
    Posts
    27,424

    Re: Help with char*

    Quote Originally Posted by cic.lemur View Post
    Please can some one help me point out what's wrong with the code below. There's an intermittent error when trying to push_back into the vector.

    I need to use char* because an API I'll be using will be expecting char*
    That is not a reason to be using vector<char*>. You should rarely, if ever, need to use a vector<char*>. For one, they are too easy to mess up, and two, you are doing unnecessary work trying to make sure nothing messes up.

    You can still use a vector<char> sized appropriately, or a vector<string> if you really need a vector of strings. A char* is merely either one of the two:
    Code:
    #include <vector>
    #include <iostream>
    
    void MyFunc(char *ptr, int size)
    {
       for (int i = 0; i < size; ++i)
         ptr[i] = 'x';
    }
    
    int main()
    {
       std::vector<char> myVector(10, 'b');
       MyFunc(&myVector[0]);  
       std::cout << &myVector[0];
    }
    This usage of std::vector is discussed in Scott Meyer's book "Effective STL". Whenever an API function needs a T*, all you need to do is declare a vector<T> and give the API function the address of the first element of the vector (as I did above).

    If the API function will not change the string (a const char* is needed), then you can use vector<string> instead, since the function will not be changing the value.
    Code:
    #include <vector>
    #include <iostream>
    
    void MyFunc(const char *ptr)
    {
         std::cout << ptr << "\n";
    }
    
    int main()
    {
       std::vector<std::string> myVector;
       myVector.push_back("abc");
       myVector.push_back("123");
       MyFunc(myVector[0].c_str());
       MyFunc(myVector[1].c_str());
    }
    So as you can see, there is no need for a vector<char*> in any of the above examples.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 25th, 2009 at 11:50 PM.

  4. #4
    Join Date
    Sep 2009
    Posts
    11

    Re: Help with char*

    Thanks so much Lindley for pointing out the problem, thanks Paul for the feedback

    I'm using a vector of char* because I need to pass words, not characters to the API. It does not accept a const char*

    I would prefer to use string but so far I've been unable to find a way to convert string to char* easily.

    -edit-

    I just looked back at your reply

    vector<char> myVector(10, 'b');

    I'll check on this, thanks.

    -edit 2-

    This mean I'll need to use vector< vector<char> > to do what I want, right? Just using char* 'seems' so much simpler.
    Last edited by cic.lemur; September 26th, 2009 at 01:13 AM. Reason: added new info

  5. #5
    Join Date
    Apr 1999
    Posts
    27,424

    Re: Help with char*

    Quote Originally Posted by cic.lemur View Post
    I'm using a vector of char* because I need to pass words, not characters to the API.
    A char* is not a word, it is a pointer to a single character.

    What you are actually passing in your example is a pointer to the start of a buffer. How that buffer is created, the API doesn't care. Whether you create it with the (error-prone) char* method you have done, or a vector<char>, the API has no idea what you did to give it a pointer to a character buffer, and doesn't care how you accomplished it.

    So what Lindely showed you using vector<char> is exactly the same thing you're doing, only safer. In the end, you wind up with the same thing -- the address of the first element in a vector<char> is a char*, exactly what your API is expecting.

    Look at my sample program above using vector<char>. The MyFunc is an "API" function, with a prototype that "needs" a char*. Look how I accomplished passing a char* by using a vector<char>.

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; September 26th, 2009 at 01:16 AM.

  6. #6
    Join Date
    Sep 2009
    Posts
    11

    Re: Help with char*

    I had edited my post, but you were fast in replying :-)

    This mean I'll need to use vector< vector<char> > to do what I want, right? Just using char* 'seems' so much simpler.

  7. #7
    Join Date
    Apr 1999
    Posts
    27,424

    Re: Help with char*

    Quote Originally Posted by cic.lemur View Post
    I had edited my post, but you were fast in replying :-)

    This mean I'll need to use vector< vector<char> > to do what I want, right? Just using char* 'seems' so much simpler.
    And in that "simplicity" is where everything is not simple. As mentioned in my previous post, a char* is only a pointer to a single character. You have to now manage all of the memory management.

    The API function doesn't take just a "char*", as you stated, it takes something else. If it were just a char* as in my post, everything given to you by Lindely and myself would work (and the function would look like my sample).

    Why not post the prototype of the API function in question?

    Regards,

    Paul McKenzie

  8. #8
    Join Date
    Sep 2009
    Posts
    11

    Re: Help with char*

    I don't know what happened, when I looked back at the api header it says it a const char* (SDL_ttf), sure enough it accepts a const char* and c_str() as well.

    I guess I won't be needing the vector<char> thing, turned out it takes less code than using char*.

    Code:
    #include <iostream>
    #include <vector>
    
    using namespace std;
    
    int main()
    {
    
        const char* s = "The quick brown fox jumps over the lazy dog The quick brown's";
    
        vector< vector<char> > textarray;
    
        textarray.resize(textarray.size()+1);
    
        for (int i = 0; i < strlen(s); i++)
        {
            textarray[textarray.size()-1].push_back(s[i]);
    
            if (s[i] == ' ')
            {
                textarray[textarray.size()-1].push_back(NULL);
                textarray.resize(textarray.size()+1);
            }
        }
        textarray[textarray.size()-1].push_back(NULL);
    
        for (int i=0; i < textarray.size(); i++)
        {
            cout << "display : " << &textarray[i][0] << endl;
        }
    
        return 0;
    }
    If I do use vector<char> or vector <string>, I don't need to manually delete (free it's memory) right?
    Last edited by cic.lemur; September 26th, 2009 at 01:55 AM.

  9. #9
    Join Date
    Apr 1999
    Posts
    27,424

    Re: Help with char*

    Quote Originally Posted by cic.lemur View Post
    If I do use vector<char> or vector <string>, I don't need to manually delete (free it's memory) right?
    That's right. You don't do any memory mamangement.

    The only thing you need to watch out for (for vector<char>) is that you still can overrun the boundaries of the vector. For example, if your vector can only hold 4 characters, and you attempt to access the 5th character in the vector using operator [], you are making an out-of-bounds access, and anything can happen at that point.

    So you must make sure your vector is sized correctly. Other than that, all other memory management is done by vector, and you do not need to concern yourself with it.

    Regards,

    Paul McKenzie

  10. #10
    Join Date
    Sep 2009
    Posts
    11

    Re: Help with char*

    Thanks a lot Paul, you were very helpful

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center