I'm new to c++, so I guess I fell into a newbyes C++ pitfall.
I tried to do the following:
QString sdkInstallationDirectory=getenv("somEnv");
QString someSourceDir=sdkInstallationDirectory+"\\Data\\"+someReference+ "\\src";
and I get a segmentation fault.
I guess this is because of the concatenation of the const chars and insufficient memory allocated to the someSourceDir QString.
What exactly is my mistake? How can I do this concatenation?
char * getenv ( const char * name );
A null-terminated string with the value of the requested environment
variable, or NULL if that environment variable does not exist.
Why you not check result?
EDIT.
So, check pointer is not necessary.
For historical reasons, QString distinguishes between a null string
and an empty string. A null string is a string that is initialized
using QString's default constructor or by passing (const char *)0 to
the constructor.
You can't add strings together with a +. Try using a stringstream.
Something like:
stringstream ss;
ss << sdkInstallationDirectory << "\Data\" + someReference << "\src";
string str = ss.str();
Although, if you are using Qt, you shouldn't be joining paths as strings.
See How to build a full path string (safely) from separate strings?
Thank you all for your answers.
It appears that I was wrong, and the segmentation fault was caused a line before, where I created the reference I mentioned in the question.
I discovered it with further debugging.
Sorry for the confusion, and thank you again!
Related
I'm trying to convert the address of a pointer to a wxString of the wxWidgets library.
I have this book that presents a console based example to explain the input/output stream system in C++. Here we can print the address of some pointers without much complications using
const char *const variable = "again";
cout << static_cast<void*>(variable);
So far I can understand the example but (Now the complication)I want to make some GUI off the examples to train myself and explore the wxWidgets classes along with the book. I've successfully made some conversions with the As() method of the wxAny class and even compiled it without warnings or errors. But in execution time I get an "Assert failure" when trying to convert the types.
If I let the program continue it prints in my wxTextCtrl things like:
ﻌњ̎X(
Any ideas??
(btw I use CodeBlocks with Mingw32 and wxWidgets 3.0 in a windows 7 system)
this is the code that gives me the assert failure:
void ConsoleFrame::OnbtnFrase2Click(wxCommandEvent& event)
{
string chaine2("Value of the pointer: ");
void* puntero = &chaine2;
wxAny anyThing= puntero;
consoleText->AppendText(anyThing.As<wxString>());
}
This is the method that gives me the assert failure error.
Thanks to #Grady for correcting the code before.
Seems that I cannot convert a void* to a wxString. I have a gist of what may the problem be but, I cannot find a solution to the original problem of printing the address of a pointer in a text control (NOT the console screen)
A common way to do what you want in C++ is using std::stringstream (you need to #include <sstream>). The body of your function would then look like this:
string chaine2("Value of the pointer: ");
void* puntero = &chaine2;
stringstream tmpss;
tmpss << chaine2 << puntero;
consoleText->AppendText(tmpss.str());
If you just want to get a wxString containing everything that was output to that stream, you just do something like:
wxString mystr = tmpss.str();
I don't know what your question has to do with wxWidgets, but this works for me:
const char * dog = "dog";
std::cout << &dog;
I am no C++ expert.. but to me that looks like "output address of variable dog"
and if you want that as a string you could use a C++ string stream or just happy old C sprintf
char * addrString = (char *)malloc(sizeof(void *) * 2 + 3); // *2 bytes for hex rep, +3 for "0x" and null
sprintf(addrString, "%p",dog);
There is a difference between the address of a pointer and the contents of the pointer, especially with C-style (nul terminated sequence of characters).
For example:
const char * const text = "Some Text\n";
The variable text is a pointer to a string literal. The contents of the pointer is the location where the string literal resides; often called an address.
The expression, &text, represents the location or the address of the pointer. So if the pointer is residing at address 0x4000, the expression &text would return 0x4000; not the content of the pointer.
There are examples on StackOverflow for printing the address of a variable and the contents or the C-Style string.
So, do you want a wxString containing the address of a pointer or the string literal that the pointer points to?
At last!!
The answer to my question was here:
http://docs.wxwidgets.org/trunk/classwx_text_ctrl.html
This is the documentation of the text control. I just had to REDIRECT the output stream to the text control with:
wxStreamToTextRedirector redirect(myTextControl);
And now I use the cout object normally,
cout<<puntero;
and the output will be presented in the text control instead of a console screen. I could not create the wxString containing the address but so far this can at least show it. I know that from here on I can create a string from the contents of the text control and the member functions of it. If any of you guys have a better answer, I will gladly accep it. It is funny how the chapter of the book where I am is in/out streams and the solution to my problem is not presented in the book.
Ps: This is more of a conceptual question.
I know this makes things more complicated for no good reason, but here is what I'm wondering. If I'm not mistaken, a const char* "like this" in c++ is pointing to l and will be automatically zero terminated on compile time. I believe it is creating a temporary variable const char* to hold it, unless it is keeping track of the offset using a byte variable (I didn't check the disassembly). My question is, how would you if even possible, add characters to this string without having to call functions or instantiating strings?
Example (This is wrong, just so you can visualize what I meant):
"Like thi" + 's';
The closest thing I came up with was to store it to a const char* with enough spaces and change the other characters.
Example:
char str[9];
strcpy(str, "Like thi")
str[8] = 's';
Clarification:
Down vote: This question does not show any research effort; it is unclear or not useful
Ok, so the question has been highly down voted. There wasn't much reasoning on which of these my question was lacking on, so I'll try to improve all of those qualities.
My question was more so I could have a better understanding of what goes on when you simply create a string "like this" without storing the address of that string in a const char* I also wanted to know if it was possible to concatenate/change the content of that string without using functions like strcat() and without using the overloaded operator + from the class string. I'm aware this is not exactly useful for dealing with strings in C++, but I was curious whether or not there was a way besides the standard ways for doing so.
string example = "Like thi" + "s"; //I'm aware of the string class and its member functions
const char* example2 = "Like this"; //I'm also aware of C-type Strings (CString as well)
It is also possible that not having English as my native language made things even worst, I apologize for the confusion.
Instead of using a plain char string, you should use the string library provided by the C++ library:
#include <string>
#include <iostream>
using namespace std;
int main()
{
string str = "Like thi";
cout << str << endl;
str = str + "s";
cout << str << endl;
return 0;
}
Normally, it's not possible to simply concatenate plain char * strings in C or C++, because they are merely pointers to arrays of characters. There's almost no reason you should be using a bare character array in C++ if you intend on doing any string manipulations within your own code.
Even if you need access to the C representation (e.g. for an external library) you can use string::c_str().
First, there is nothing null terminated, but the zero terminated. All char* strings in C end with '\0'.
When you in code do something like this:
char *name="Daniel";
compiler will generate a string that has a contents:
Daniel\0
and will initialize name pointer to point at it at a certain time during program execution depending on the variable context (member, static, ...).
Appending ANYTHING to the name won't work as you expect, since memory pointed to by name isn't changeable, and you'll probably get either access violation error or will overwrite something else.
Having
const char* copyOfTheName = name;
won't create a copy of the string in question, it will only have copyOfTheName point to the original string, so having
copyOfTheName[6]='A';
will be exactly as
name[6]='A';
and will only cause problems to you.
Use std::strcat instead. And please, do some investigating how the basic string operations work in C.
when I use strtok to tokenize a c++ string, it happens a confusing problem, see the simple code below:
void a(string s){
strtok((char*)s.c_str(), " ");
}
int main(){
string s;
s = "world hello";
a(s);
cout<<s<<endl;
return 0;
}
the program outputs "world".
Shouldn't it output "world hello"? Because I pass the string as a value parameter to function a, the strtok shouldn't modify the original s...
Can anyone explain this trick.
thank you.
The problem is (char*)s.c_str(), you are casting the constness away and modified the string contents in a way that you are not supposed to. While the original s should not be modified, I pressume you may have been hit by a smart optimization that expects you to play by the rules. For instance, a COW implementation of string would happen to show that behavior.
c_str() returns a const pointer, which is a promise to the compiler that the thing being pointed at won't be modified. And then you're calling strtok which modifies it.
When you lie to the compiler, you will be punished.
That's the way strtok() works. It use the first parameter as a buffer. By casting it to a char*, you allow it to modify the string. strtok() does not known about the original std::string. It also store the string pointer in a static variable, that's why you have to call it with a null pointer the next times to continue to parse the same string.
By the way, in c++, you should use std::istringstream instead. It does not use an internal static variable, which is not thread-safe. And you can extract the parameters directly into int, double, etc like we do with cin. std::ostringstring replace sprintf().
Consider the following snippet that uses strtok to split the string madddy.
char* str = (char*) malloc(sizeof("Madddy"));
strcpy(str,"Madddy");
char* tmp = strtok(str,"d");
std::cout<<tmp;
do
{
std::cout<<tmp;
tmp=strtok(NULL, "dddy");
}while(tmp!=NULL);
It works fine, the output is Ma. But by modifying the strtok to the following,
tmp=strtok(NULL, "ay");
The output becomes Madd. So how does strtok exactly work? I have this question because I expected strtok to take each and every character that is in the delimiter string to be taken as a delimiter. But in certain cases it is doing that way but in few cases, it is giving unexpected results. Could anyone help me understand this?
"Trying to understand strtok" Good luck!
Anyway, we're in 2011. Tokenise properly:
std::string str("abc:def");
char split_char = ':';
std::istringstream split(str);
std::vector<std::string> token;
for (std::string each; std::getline(split, each, split_char); token.push_back(each));
:D
Fred Flintstone probably used strtok(). It predates multi threaded environments and beats up (modifies) the source string.
When called with NULL for the first parameter, it continues parsing the last string. This feature was convenient, but a bit unusual even in its day.
It seems you forget that you have call strtok the first time (out of loop) by delimiter "d".
The strtok is working fine. You should have a reference here.
For the second example(strtok("ay")):
First, you call strtok(str, "d"). It will look for the first "d", and seperate your string. Specifically, it sets tmp = "Ma", and str = "ddy" (dropping the first "d").
Then, you call strtok(str, "ay"). It will look for an "a" in str, but since your string now is only "ddy", no matching occurs. Then it will look for an "y". So str = "dd" and tmp = "".
It prints "Madd" as you saw.
Actually your code is wrong, no wonder you get unexpected results:
char* str = (char*) malloc(sizeof("Madddy"));
should be
char* str = (char*) malloc(strlen("Madddy") + 1);
I asked a question inspired from another question about functions causing security problems/bad practise functions and the c standard library.
To quote the answer given to me from there:
A common pitfall with the strtok()
function is to assume that the parsed
string is left unchanged, while it
actually replaces the separator
character with '\0'.
Also, strtok() is used by making
subsequent calls to it, until the
entire string is tokenized. Some
library implementations store
strtok()'s internal status in a
global variable, which may induce some
nasty suprises, if strtok() is
called from multiple threads at the
same time.
As you've tagged your question C++, use something else! If you want to use C, I'd suggest implementing your own tokenizer that works in a safe fashion.
Since you changed your tag to be C and not C++, I rewrote your function to use printf so that you can see what is happening. Hoang is correct. You seeing correct output, but I think that you are printing everything on the same line, so you got confused by the output. Look at Hoang's answer as he explains what is happening correctly. Also, as others have noted, strtok destroys the input string, so you have to be careful about that - and it's not thread safe. But if you need a quick an dirty tokenizer, it works. Also, I changed the code to correctly use strlen, and not sizeof as correctly pointed out by Anders.
Here is your code modified to be more C-like:
char* str = (char*) malloc(strlen("Madddy") + 1);
strcpy(str,"Madddy");
char* tmp = strtok(str,"d");
printf ("first token: %s\n", tmp);
do
{
tmp=strtok(NULL, "ay");
if (tmp != NULL ) {
printf ("next token: %s\n", tmp);
}
} while(tmp != NULL);
I came across a subtle bug a couple of days ago where the code looked something like this:
ostringstream ss;
int anInt( 7 );
ss << anInt << "HABITS";
ss << ends;
string theWholeLot = ss.str();
The problem was that the ends was sticking a '\0' into the ostringstream so theWholeLot actually looked like "7HABITS\0" (i.e. a null at the end)
Now this hadn't shown up because theWholeLot was then being used to take the const char * portion using string::c_str() That meant that the null was masked as it became just a delimiter. However, when this changed to use strings throughout, the null suddenly meant something and comparisons such as:
if ( theWholeLot == "7HABITS" )
would fail. This got me thinking: Presumably the reason for ends is a throwback to the days of ostrstream when the stream was not normally terminated with a null and had to be so that str() (which then cast out not a string but a char *) would work correctly.
However, now that it's not possible to cast out a char * from a ostringstream, using ends is not only superfluous, but potentially dangerous and I'm considering removing them all from my clients code.
Can anyone see an obvious reason to use ends in a std::string only environment?
You've essentially answered your own question is as much detail that's needed. I certainly can't think of any reason to use std::ends when std::string and std::stringstream handle all that for you.
So, to answer your question explicitly, no, there is no reason to use std::ends in a std::string only environment.
There are some APIs that expect a "string array" with multiple zero terminated strings, a double zero to mark the end. Raymond Chang just recently blogged about it, most of all to demonstrate how often that this gets fumbled.