I am trying to run the following code
TCHAR* str1 = TEXT("C:\\Program Files\\Internet Explorer;");
const TCHAR* del = TEXT(";");
TCHAR* token = _tcstok(str1, del);
When I run this in VS 2010 I get the following Exception :
Unhandled exception at 0x10275af4 (msvcr100d.dll) in String_Tchars.exe: 0xC0000005: Access violation writing location 0x0041839c.
My Objecttive to to be able to get the part before the semi-colon ";" and then do an append to that token to get the final string as c:\Program Files\Internet Explorer\iexplore.exe
Could someone shed some light what is causing this exception?
You can only use strtok() (and its Windows relatives) with modifiable strings. So make your strings local character arrays:
TCHAR str1[] = TEXT("C:\\Program Files\\Internet Explorer;");
TCHAR* token = _tcstok(str1, ";");
// etc.
The the tokenizer function actually modifies the string by replacing the delimiter by null bytes, so there's no way you can use this on a read-only string.
If your string comes to you through a pointer-to-const, copy it to a local array first (e.g. to a std::vector<TCHAR>):
void foo(const TCHAR * str)
{
std::vector<TCHAR> s(str, _tcslen(str) + 1); // local copy, includes null terminator
TCHAR * str1 = s.data(); // or &s[0]
TCHAR* token = _tcstok(str1, ";");
// ...
}
_tcstok tries to modify the constant string(string Literal) causing an Undefined Behavior, which presents itself in the form of an access violation.
The string Literal I refer to here is:
TCHAR* str1 = TEXT("C:\\Program Files\\Internet Explorer;");
^^^^
The program should not modify it, and _tcstok tries to do that hence the Undefined Behavior.
Instead use modifyable non const string array:
TCHAR str1[] = TEXT("C:\\Program Files\\Internet Explorer;");
Related
Hello i've had this break point being thrown by xstring for the last two days and I can't seem to get rid of it. First off the class i'm working with or at least the relevant bit.
class myProjects {
public:
std::wstring wstr;
const wchar_t* BrowserPtr = wstr.c_str();
std::string browser = "undeffined";
};
with that out of the way here is whats generating the error
void myProjects::setBrowser(std::string &str) {
std::string cpy = str;
browser = str; // this is the problimatic line
wchar_t temp[21];
size_t outSize;
mbstowcs_s(&outSize, temp, sizeof temp, str.c_str(), str.size());
wstr.assign(temp);
}
at least that's my goal the string definition alone still throws the error.
so here's the error.
Exception thrown: read access violation. this was 0x14.
and the surrounding code snippet
basic_string& assign(_In_reads_(_Count) const _Elem* const _Ptr, _CRT_GUARDOVERFLOW const size_type _Count) {
// assign [_Ptr, _Ptr + _Count)
if (_Count <= _Mypair._Myval2._Myres) { //here
_Elem* const _Old_ptr = _Mypair._Myval2._Myptr();
_Mypair._Myval2._Mysize = _Count;
_Traits::move(_Old_ptr, _Ptr, _Count);
_Traits::assign(_Old_ptr[_Count], _Elem());
return *this;
}
Now I've tried a lot to get rid of this and I know that if I watch the variable browser in the debugger it says its information is unreadable and calling things like get capacity throw errors on read access as well. I do use strings else where in the program and even change wstrings and string back and forth but this is a new error. I also tried making browser private and a getBrowser function that was this.
People seemed to think by unreadable I meant garbage so I attached a screenshot of the dubugger.
std::string myProjects::getBrowser() {
//std::string s(wstr.begin(), wstr.end());
std::string newStr = "";
return newStr;
}
with or without commented out line it throws same error. Further more putting the copy and pasted code snippet that generate the error into the error alone don't in a new project. Im just looking for some insight as to why this , might be happening. I am not using pointers in either function and the 0x14 is weird but if I try to reserve space same error. Frankly i'm just really confused and don't know what to do. I realize i didn't give something to throw in a compiler and i'm sorry but I really have no idea where the error would be dirrvided from or what types of things cause this error all i could find online was null pointers.
sorry for typos.
A possible problem can be found in class myProjects:
class myProjects {
public:
std::wstring wstr;
const wchar_t* BrowserPtr = wstr.c_str();
std::string browser;
};
When a variable of type myProjects is constructed, first wstr is constructed with an empty string, then BrowserPtr is initialized with a pointer to the data portion of the then empty string wstr.
However, as soon as you assign anything to wstr, it is quite likely that it frees the internal data buffer, and allocates a new one to hold the new string. This means that BrowserPtr is now pointing to a piece of memory that has been freed.
As PaulMcKenzie already mentions, don't store BrowserPtr this way, omit it from the class. Instead, the moment you need to pass a C string to another function, call wstr.c_str().
Another issue is with the multibyte conversion:
wchar_t temp[500];
size_t outSize;
mbstowcs_s(&outSize, temp, size_t(256), str.c_str(), str.size());
First, why have an array of length 500 but pass 256 to mbstowcs_s()? It is better to ensure the values match:
mbstowcs_s(&outSize, temp, sizeof temp / sizeof *temp, str.c_str(), str.size());
Also note that if the input string is as large or larger than the length you pass to mbstowcs_s(), then there will be no null wide character written to the output. Either you have to check the result to ensure the result is shorter than the size of the output buffer, or you have to ensure you always add a null wide character at the end of the output buffer:
temp[(sizeof temp / sizeof *temp) - 1] = L'\0';
Of course, it's even better to first call mbcstowcs(nullptr, str.c_str(), 0) to get the required length of the output buffer. Then it is possible in C++17 to resize wstr to the right length, and pass wstr.data() to mbcstowcs() as the output buffer.
I am trying to get the current executable path into a string by using this code (I have tried several other versions of it too, but none of them really works, I always get a access violation at some point)
char *filename = new char[MAX_PATH + 1];
GetModuleFileName(NULL, filename, MAX_PATH);
string exe = filename;
This fails with an access violation at the first line for some reason. What am I missing?
This version does the error check, and also respects that GetModuleFileName works with TCHAR's (the second parameter is an LPTSTR, which is a pointer to a TCHAR).
#include <windows.h>
#include <string>
typedef std::basic_string<TCHAR> TCharString;
int main()
{
TCHAR filename[MAX_PATH + 1];
if ( GetModuleFileName(NULL, filename, MAX_PATH) != 0 )
{
TCharString strExe = filename;
}
}
Note that since GetModuleFileName works with TCHAR, it is not correct to blindly use std::string as the string type. Instead, create a string type based on TCHAR.
Second, the error check is done to ensure that we do not assign an invalid string to the string object.
try not using a char pointer . use a char array instead.
I made a function which change string, see the following code.
void Test(char* str, char c) {
str[1] = c;
}
int main(){
Test("Hi", '2');
}
I notice it made some run time error. I know how to prevent the error.
char buff[3] = "Hi";
Test(buff,'2');
but I don't know why the first example made run time error. I guess, if I pass string directly, it becomes const char. Does anyone explain what happened exactly?
ps.
what if I use char* str = "hi", then pass it into the argument?
char* buff = "Hi";
Test(buff,'2');
like this. Can I modify buff?
Because "Hi" is string literal and it's not allowed to be modified, they are read-only (the type of string literal is const char[n]).
Modifying it is undefined behavior.
Regarding your edit: char* str = "hi" is invalid, it should be const char* str = "hi". Which is pointer to const char. Again, modifying it is disallowed.
When you don't explicitly allocate memory for strings, compiler stores them in read-only memory. So, any modification to such strings result in run time error.
Test("Hi", '2');
Here in the above case "Hi" string is stored in read-only memory.
char *buff = "Hi";
Test(buff,'2');
Here also "Hi" is stored in the read-only memory and the starting address is returned to buff character pointer, which is same as above. You can overcome such errors by allocating memory for the string and then pass that reference. Like
char buff[3] = "Hi";
Test(buff,'2');
or
char *buff = (char *)malloc(SIZE);
strcpy(buff, "Hi");
Test(buff,'2');
Please refer to this link http://www.geeksforgeeks.org/memory-layout-of-c-program/
Often string constants are in read-only memory, causing a runtime error when you attempt to modify it.
In your second example, you put the string into a buffer on the stack, so it can be updated without error.
Literal strings are not modifiable. When I compile your code with GCC I get the warning:
testptr.cpp:6: warning: deprecated conversion from string constant to 'char*'
Runtime Error:
char* buff = "Hi"; // buff points to an address in the code-section, which is a Read-Only section
buff[1] = 'x'; // Illegal memory access violation
Compilation Error:
const char* buff = "Hi"; // This is a correct declaration, which will prevent the runtime error above
buff[1] = 'x'; // The compiler will not allow this
All Good:
char buff[] = "Hi"; // buff points to an address in the stack or the data-section, which are both Read-Write sections
buff[1] = 'x'; // Works OK
Notes:
In all cases, a string "Hi" is placed in the code-section of the program.
In the last example, the contents of that string are copied into the buff array.
In the last example, the buff array is located in the stack if buff is a non-static local variable, and in the data-section of the program otherwise.
Code:
const char* copyoutmsg(unsigned char instring[2055])
{
char* msg = "";
const char* wholestring = reinterpret_cast<const char*>(instring);
strncpy(msg,wholestring,eotpos-5);
printf("Message: %s\n",msg);
return msg;
}
It's seg faulting (process returning 139) - can't get my head round it. Eotpos is the position of the end of the message. What this function is meant to do is input an unsigned char array, convert it to const char and return the message minus 5 chars from the end. I cannot see what is causing this.
Ignoring all other problems in your code, segfault source is in these statements:
char* msg = "";
const char* wholestring = reinterpret_cast<const char*>(instring);
strncpy(msg,wholestring,eotpos-5);
You're trying to copy the string pointed by wholestring into a memory location where msg is pointing to. msg is pointing in the read-only part of the memory, where the string literals are stored (see the first statement of your code). You need to allocate memory for the message first:
char* msg = new char[eotpos - 5 + 1];
const char* wholestring = reinterpret_cast<const char*>(instring);
strncpy(msg,wholestring,eotpos-5);
Don't forget to delete memory afterwards!
Note that you cannot initialize a char* from a string literal in C++11. The clause which allowed that initialization in C++98 and C++03 was removed. If you worked out why that is, you have a hint on one thing which went wrong! You may want to read up on memory allocation as well or, better yet, use proper C++ facilities like std::string as raw pointer manipulators are fairly hard to get right.
I might be wrong, but you don't allocate any memory for msg, of course it will segfault if you try to copy a string to it.
Besides, if eotpos is the position of the last message character (and it does not point to the string termination literal), the message has the length of eotpos+1 (without the string termination literal), since the counting starts with 0. That is why you will have to allocate eotpos+1-5+1 characters for msg (the last +1 is being used for the string termination literal).
Initialize msg like this:
char* msg = malloc(eotpos-3); // Or new char[eotpos - 3], when I answered, there was still just the C tag
msg[eotpos-4] = 0;
And then copy:
strncpy(msg,wholestring,eotpos-4);
Well, depending on what eotpos really is, you have to fix the constant values above. But in my opinion, your description is a little value.
I want to convert a CString into a char[]. Some body tell me how to do this?
My code is like this :
CString strCamIP1 = _T("");
char g_acCameraip[16][17];
strCamIP1 = theApp.GetProfileString(strSection, _T("IP1"), NULL);
g_acCameraip[0] = strCamIP1;
This seems to be along the right lines; http://msdn.microsoft.com/en-us/library/awkwbzyc.aspx
CString aCString = "A string";
char myString[256];
strcpy(myString, (LPCTSTR)aString);
which in your case would be along the lines of
strcpy(g_acCameraip[0], (LPCTSTR)strCamIP1);
From MSDN site:
// Convert to a char* string from CStringA string
// and display the result.
CStringA origa("Hello, World!");
const size_t newsizea = (origa.GetLength() + 1);
char *nstringa = new char[newsizea];
strcpy_s(nstringa, newsizea, origa);
cout << nstringa << " (char *)" << endl;
CString is based on TCHAR so if don't compile with _UNICODE it's CStringA or if you do compile with _UNICODE then it is CStringW.
In case of CStringW conversion looks little bit different (example also from MSDN):
// Convert to a char* string from a wide character
// CStringW string. To be safe, we allocate two bytes for each
// character in the original string, including the terminating
// null.
const size_t newsizew = (origw.GetLength() + 1)*2;
char *nstringw = new char[newsizew];
size_t convertedCharsw = 0;
wcstombs_s(&convertedCharsw, nstringw, newsizew, origw, _TRUNCATE );
cout << nstringw << " (char *)" << endl;
You could use wcstombs_s:
// Convert CString to Char By Quintin Immelman.
//
CString DummyString;
// Size Can be anything, just adjust the 100 to suit.
const size_t StringSize = 100;
// The number of characters in the string can be
// less than String Size. Null terminating character added at end.
size_t CharactersConverted = 0;
char DummyToChar[StringSize];
wcstombs_s(&CharactersConverted, DummyToChar,
DummyString.GetLength()+1, DummyString,
_TRUNCATE);
//Always Enter the length as 1 greater else
//the last character is Truncated
If you are using ATL you could use one of the conversion macros. CString stores data as tchar, so you would use CT2A() (C in macro name stands for const):
CString from("text");
char* pStr = CT2A((LPCTSTR)from);
Those macros are smart, if tchar represents ascii (no _UNICODE defined), they just pass the pointer over and do nothing.
More info below, under ATL String-Conversion Classes section:
http://www.369o.com/data/books/atl/index.html?page=0321159624%2Fch05.html
CStringA/W is cheaply and implicitly convertible to const char/wchar_t *. Whenever you need C-style string, just pass CString object itself (or the result of .GetString() which is the same). The pointer will stay valid as long as string object is alive and unmodified.
strcpy(g_acCameraip[0], strCamIP1);
// OR
strcpy(g_acCameraip[0], strCamIP1.GetString());
If you need writable (non-const) buffer, use .GetBuffer() with optional maximum length argument.
If you have CStringW but you need const char* and vice versa, you can use a temporary CStringA object:
strcpy(g_acCameraip[0], CStringA(strCamIP1).GetString());
But a much better way would be to have array of CStrings. You can use them whereever you need null-terminated string, but they will also manage string's memory for you.
std::vector<CString> g_acCameraip(16);
g_acCameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
Use memcpy .
char c [25];
Cstring cstr = "123";
memcpy(c,cstr,cstr.GetLength());
Do you really have to copy the CString objects into fixed char arrays?
enum { COUNT=16 };
CString Cameraip[COUNT];
Cameraip[0] = theApp.GetProfileString(strSection, _T("IP1"), NULL);
// add more entries...
...and then - later - when accessing the entries, for example like this
for (int i=0; i<COUNT; ++i) {
someOp(Cameraip[i]); // the someOp function takes const CString&
}
...you may convert them, if needed.
fopen is the function which needs char* param. so if you have CString as available string, you can just use bellow code.
be happy :)
Here, cFDlg.GetPathName().GetString(); basically returns CString in my code.
char*pp = (char*)cFDlg.GetPathName().GetString();
FILE *fp = ::fopen(pp,"w");
CString str;
//Do something
char* pGTA = (LPTSTR)(LPCTSTR)str;//Now the cast
Just (LPTSTR)(LPCTSTR). Hope this is what you need :)
char strPass[256];
strcpy_s( strPass, CStringA(strCommand).GetString() );
It's simple
ATL CStrings allow very simple usage without having to do a lot of conversions between types. You can most easily do:
CString cs = "Test";
const char* str = static_cast<LPCTSTR>(cs);
or in UNICODE environment:
CString cs = "Test";
const wchar_t* str = static_cast<LPCTSTR>(cs);
How it works
The static_cast (or alternatively C-Style cast) will trigger the CString::operator LPCTSTR, so you don't do any pointer reinterpretation yourself but rely on ATL code!
The documentation of this cast operator says:
This useful casting operator provides an efficient method to access the null-terminated C string contained in a CString object. No characters are copied; only a pointer is returned. Be careful with this operator. If you change a CString object after you have obtained the character pointer, you may cause a reallocation of memory that invalidates the pointer.
Modifiable Pointers
As mentioned in the above statement, the returned pointer by the cast operator is not meant to be modified. However, if you still need to use a modifiable pointer for some outdated C libraries, you can use a const_cast (if you are sure that function wont modify the pointer):
void Func(char* str) // or wchar_t* in Unicode environment
{
// your code here
}
// In your calling code:
CString cs = "Test";
Func(const_cast<LPTSTR>(static_cast<LPCTSTR>(test))); // Call your function with a modifiable pointer
If you wish to modify the pointer, you wont get around doing some kind of memory copying to modifiable memory, as mentioned by other answers.
There is a hardcoded method..
CString a = L"This is CString!";
char *dest = (char *)malloc(a.GetLength() + 1);
// +1 because of NULL char
dest[a.GetLength()] = 0; // setting null char
char *q = (char *)a.m_pszData;
//Here we cannot access the private member..
//The address of "m_pszData" private member is stored in first DWORD of &a...
//Therefore..
int address = *((int *)&a);
char *q = (char *)address;
// Now we can access the private data!, This is the real magic of C
// Size of CString's characters is 16bit...
// in cstring '1' will be stored as 0x31 0x00 (Hex)
// Here we just want even indexed chars..
for(int i = 0;i<(a.GetLength()*2);i += 2)
dest[i/2] = *(q+i);
// Now we can use it..
printf("%s", dest);