-
September 25th, 2009, 11:23 PM
#1
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
-
September 25th, 2009, 11:28 PM
#2
Re: Help with char*
Originally Posted by cic.lemur
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.
-
September 25th, 2009, 11:45 PM
#3
Re: Help with char*
Originally Posted by cic.lemur
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.
-
September 26th, 2009, 01:02 AM
#4
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
-
September 26th, 2009, 01:13 AM
#5
Re: Help with char*
Originally Posted by cic.lemur
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.
-
September 26th, 2009, 01:17 AM
#6
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.
-
September 26th, 2009, 01:21 AM
#7
Re: Help with char*
Originally Posted by cic.lemur
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
-
September 26th, 2009, 01:53 AM
#8
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.
-
September 26th, 2009, 06:34 AM
#9
Re: Help with char*
Originally Posted by cic.lemur
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
-
September 26th, 2009, 07:13 AM
#10
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|