To me it seems like it should be so simple, but I just feel like I'm missing something.
I have in my header file a private variable _stoplist When I declared it in the header file the code looks just like this.
private:
std::string _stoplist[];
But when later in my function I decide to access this, it segfaults on anything.
_stoplist[_length];
//cout << _length << prints 104 (its a valid int and everything)
_stoplist[0] = "b";
Crashes in the std::string.assign() code with a segfault. I have a gut feeling that I'm missing something obvious here but I haven't quite found out what yet.
Thanks in advance!
EDIT: Ok, thanks for all the help. For anyone else who may read this, I would recommend to use one of the answers below since that is the smart way to do it. In my case though since I needed to dynamically allocate it without using vector I just used the following code.
private:
std::string *_stoplist;
and then in my cpp file
_stoplist = new string[_length];
Yeah, turns out that it really was way simple, and I just was over looking that part.
You're getting an array out of bounds error because _stoplist doesn't have a size. You should either give it a size, and only access elements within that range, such as:
private:
std::string _stoplist[100];
now you should be able to index _stoplist[0] through _stoplist[99]. However a better solution would probably to use std::vector instead, as it's a lot safer.
private:
std::vector< std::string > _stoplist;
Then you can use its member functions such as resize() to grow it to whatever size you need.
That's because a variable declared as std::string[] is basically just a pointer. To use it, you need to allocate memory for it. If you want to allocate fixed memory for it, try declaring it as e.g. std::string _stoplist[5]; instead.
Related
I've tried out using memcpy() method to strings but was getting a "no matching function call" although it works perfectly when I use an array of char[].
Can someone explain why?
www.cplusplus.com/reference/cstring/memcpy/
std::string is an object, not a contiguous array of bytes (which is what memcpy expects). std::string is not char*; std::string contains char* (somewhere really deep).
Although you can pull out the std::string inner byte array by using &str[0] (see note), I strongly encourage you not to. Almost anything you need to do already is implemented as a std::string method. Including appending, subtracting, transforming and anything that makes sense with a text object.
So yes, you can do something as stupid as:
std::string str (100,0);
memcpy(&str[0],"hello world", 11);
but you shouldn't.
Even if you do need memcpy behaviuor, try to use std::copy instead.
Note: this is often done with C functions that expects some buffer, while the developer wants to maintain a RAII style in his code. So he or she produces std::string object but passes it as C string. But if you do clean C++ code you don't need to.
Because there's no matching function call. You're trying to use C library functions with C++ types.
I have a problem with my code, it seems to fail in a weird way in release mode, debug mode works just fine.
I am out of ideas and clues. I would like to get a direction for what should i do.
So here is the problematic code:
static inline void FindPoint(Line *First,AABB *Second,point *Pt,int direction)
{
std::vector<point*> pntvec; ... }
When i call function FindPoint it is all fine and everything is set well.
But when i reach the vector initialization the First pointer is reset to the same address as the vector.
That causes unexpected behavior.
So i thought the problem was in the commonalities. Both Line and the vector are using the point structure.
Yet i was not able to find anything unusual.
here are the structures
typedef struct
{
double x;
double y;
}point;
typedef struct
{
double incline;
double y;
double x;
double c;
point start,finish;
}Line;
And here is the initialization of the data sent to parameter First:
Line *objvec = new Line;
so what could be the problem can any one tell?
Thank you in advance
Edit:
A better look at the code
http://pastebin.com/rki7EdM6
You're using pointers more heavily than you should for these simple types. Pointers and dynamic allocation are the likely sources of your undefined behavior. So a simple first step is to refactor and clean up your code, preferring stack variables and pass-by-reference for simple types. In all likelihood, the undefined behavior will go away, or the error will be easier to spot.
[Caveat: I can't get to pastebin, so I can't see your full code. Prefer simple examples right here on the site]
For example, your function signature should probably be this (I'm guessing about which parameter is the output)
static inline point FindPoint(const Line &First, const AABB &Second,int direction)
And
Line *objvec = new Line;
should just be
Line objvec;
etc, etc.
std::vector<point> pntvec;
is probably the most important. A vector of pointers is ok, but should be avoided if possible. One of the nice parts about standard containers is the auto-cleanup when the variable goes out of scope. You don't get that with a vector of pointers, since the vector doesn't know to call delete on every element. You have to do it yourself.
"so what could be the problem can any one tell?"
If such a situation occurs, the most probable reason is, you have hit undefined behavior in your code somewhere else.
I can't tell any more from the context and code you have posted. But using a tool like valgrind is likely to do this right on your service.
This seems simple to me but I'm having trouble actually finding anything explicitly stating this.
Does std::string stringArray[3] not create an array of std::string objects, the way that SomeType typeArray[3] would? The actual number is irrelevant; I just picked 3 arbitrarily.
In the Visual Studio 2010 debugger, it appears to create a single string as opposed to an array of strings. Why?
Wild guess: is it calling the default std::string constructor, and then invoking an unused access of index 3? If so, why doesn't that cause an out of bounds exception on an empty string?
Does this have something to do with overloading the [] operator?
There are plenty of ways to code the same things without specifically using an array of std::string without issue, but what is the explanation/justification for this behavior? It seems counterintuitive to me.
Edit: I found this thread std::string Array Element Access in which the comments on the answer appear to observe the same behavior.
Visual studio's debugger will often show you only the first thing an array or pointer points to. You will have to use stringArray[1] stringArray[2] etc to see farther than that.
The OP is NOT losing his mind. But Visual Studio's integrated debugger certainly is. I believe this is a bust in the detection of operator [] for std::string, which is sad However, it does work correctly for std::vector<std::string>
An excellent reference to how you can get around this using the watch-window (no way to do it using the Auto or Locals window afaik) can be found at this previously posted question. This is also an extremely helpful method for viewing pointer-based dynamic arrays (arrays allocated with Type *p = new Type[n];). Hint: use "varname,n" where varname is the variable (pointer or fixed array), and 'n' is the number of elements to expand.
A demonstration is in order to show a declared C-array of std::string and what the OP was observing, and a std::vector<std::string> to show what things should look like:
int main(int argc, char *argv[])
{
std::string stringArray[3];
std::vector<std::string> vecStrings(3);
return 0; // set bp *here*
}
It creates an array. Either you compiled something different or you misinterpreted the results.
It doesn't create an array in these contexts:
void function(std::string stringArray[3]) { }
This function parameter is a pointer to std::string, you can't have function parameters of array type.
extern std::string strnigArray[3];
This declares but doesn't define an array. It tells the compiler there is an array of three strings somewhere in the program call stringArray but doesn't actually create it.
Otherwise, it creates an array of three strings.
You can check that with:
assert( sizeof(stringArray) == 3*sizeof(std::string) );
or in C++11
static_assert( sizeof(stringArray) == 3*sizeof(std::string), "three strings" );
Yeah the debugger in VS 2010 doesn't do a great job here, but as others have said, it's only a display issue in the debugger, it does work as you'd expect.
In VS 2012 they've done a much better job :-
Okay, I have a struct, TextBlock, that simulates moving blocks of text around the screen. Here's the header:
struct TextBlock
{
RECT textArea;
RECT rectArea;
double whatBlock;
double x;
double y;
double angle;
double speed;
double width;
double height;
char *word;
bool stuck;
};
When it's like this, everything works perfectly fine. The problem comes when I add another member that I need. The way it works is that I have two arrays of TextBlocks. The first is for moving ones, the second is for ones that don't move, signifying where the moving ones need to go. The words are all randomized from a sentence to a jumble, so this data member will be set (commented out) to the index of which static block belongs to the moving one so I know when it's in the right place.
int whatBlock;
After creating this, I go through all of the created objects and set
tb[i][j].whatBlock = 0; //same area as other data members being set, moving text
stb[i][j].whatBlock = 0; //static text block
When I try to run this, without doing anything else to the data member, it comes up with an error:
The instruction at [address] referenced memory at [different address]. The memory could not be "written".
Note that if I don't try to modify it, and just create the data member, it works.
At this point of almost being done and having tons of these kinds of problems, I'm getting a bit fed up with this program >.> Any help at all on this would be greatly appreciated.
EDIT: This issue is now fixed. I replied to the accepted answer with the explanation, but it poses another problem, even if it doesn't affect this program.
Force a rebuild of everything. You may have an object file that is out-of-date with respect to the header file that defines TextBlock
If that doesn't fix it, run your program under a debugger and see what the faulting instruction is. Either that will allow you to fix the program, or you can ask again with mroe informatin.
Without you posting more code, I can only tell that you likely have a memory corruption bug in your program - i.e. you are reading or writing beyond the end of allocated memory.
If you post more code, I'll edit this answer accordingly.
I can't really give advices since we cannot access the complete source code.
Anyway, I can suggest you that it may be not in the struct TextBlock where really hides the bug. For instance, every access to TextBlock's member means that you are accessing to this hidden variable.
If this pointer is corrupted, you may experience problem where you don't expect it, leading you to search in the wrong places.
Rather simple question.
Where should I store error,exception, user messages?
By far, I always declared local strings inside the function where it is going to be invoked and did not bother.
e.g.
SomeClass::function1(...)
{
std::string str1("message1");
std::string str2("message2");
std::string str3("message3");
...
// some code
...
}
Suddenly I realized that since construction & initialization are called each time and it might be quite expensive. Would it be better to store them as static strings in class or even in a separate module?
Localization is not the case here.
Thanks in advance.
Why not just use a string constant when you need it?
SomeClass::function1(...)
{
/* ... */
throw std::runtime_error("The foo blortched the baz!");
/* ... */
}
Alternately, you can use static const std::strings. This is appropriate if you expect to copy them to a lot of other std::strings, and your C++ implementation does copy-on-write:
SomeClass::function1(...)
{
static const std::string str_quux("quux"); // initialized once, at program start
xyz.someMember = str_quux; // might not require an allocation+copy
}
If you expect to make lots of copies of these strings, and you don't have copy-on-write (or can't rely on it being present), you might want to look into using boost::flyweight.
TBH its probably best to ONLY construct error messages when they are needed (ie if something goes badly wrong who cares if you get a slowdown). If the messages are always going to appear then its probably best to define them statically to avoid the fact that they will be initialised each time. Generally, though, I only display user messages in debug mode so its quite easy to not show them if you are trying to do a performance build. I then only construct them when they are needed.