XString breakpoint thrown when defining string - c++

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.

Related

C++ Windows function "LockResource()" returns half the data in the resource

I am trying to read an embedded resource from a dll, it contains an encrypted file. Reading it from LockResource() , only returns half the data.
The funny thing is that I checked SizeOfResource() and the size of the resource is what it is supposed to be.
So I tried to access the file without it being an embedded resource :
std::ifstream enc("Logs.enc" , std::ios::binary); // Accessing encrypted file
std::string ciphertext = std::string((std::istreambuf_iterator<char>(enc)), std::istreambuf_iterator<char>());
int size = ciphertext.size(); // Returns the correct size
This worked , I tried to find something they have in common and I tried to remove the std::ios::binary and it had similar behavior to when accessing the file as a resource.
Here is my attempt to Access it as a resource :
HGLOBAL SHEET_DATA; // Imagine this has the encrypted file
if (SHEET_DATA) {
char* datac = nullptr;
datac = (char*)LockResource(SHEET_DATA);
std::string data = datac;
long size_sheet = SizeofResource(dll, SHEET); //
int real_size = data.size(); // Returns the wrong size
}
I tried to search if there was anything such as a LockResource() function that accessess the data in binary mode , but I couldn't find any results.
Thank you
strlen is assuming the parameter is a zero terminated string. It counts the chars until it gets to the zero termination.
In your case it seems like the resource is binary. In this case it may contain bytes with the value 0, which strlen treats as the end of the string.
Therefore what strlen returns is irrelevant. You can use size_sheet returned from SizeofResource to know the size of the data pointed by datac.
Update:
The updated question does not contain a usage of strlen anymore. But the line:
std::string data = datac;
Create a similar problem. Initializing an std::string from a char* assumes the char* is pointing to a zero terminated string. So if the buffer contains zeroes the resulting string will contain only the characters till the first zero.
You can initialize the std::string the following way to avoid the assumption of the zero termination:
std::string data(datac, size_sheet);
Giving the length of the buffer to the ctor of std::string will force initializing with the complete buffer (ignoring the zeroes).
Update2: As #IInspectable commented below, if the data is not really a string, better hold it in a more suitable container - e.g. std::vector<char>. It also has a constructor accepting a char* and the buffer's length.
The problem is this line:
std::string data = datac;
This constructs a std::string from a null-terminated string. But datac is not a null-terminated string, as you said it's binary data. Instead, use the string (const char* s, size_t n); ctor overload:
std::string data(datac, size_sheet);

Memory leak when using smart pointers

Consider the following function:
unique_ptr<char> f(const wstring key, const unsigned int length)
{
assert(length <= key.length());
const wstring suffix = key.substr(length, key.length() - length);
const size_t outputSize = suffix.length() + 1; // +1 for null terminator
char * output = new char[outputSize];
size_t charsConverted = 0;
const wchar_t * outputWide = suffix.c_str();
wcstombs_s(&charsConverted, output, outputSize, outputWide, suffix.length());
return unique_ptr<char>(output);
}
The intent here is to accept a wstring, select length characters from the end, and return them as a C-style string that's wrapped in a unique_ptr (as required by another library - I certainly didn't chose that type :)).
One of my peers said in passing that he thinks this leaks memory, but he didn't have time to elaborate, and I don't see it. Can anybody spot it, and if so explain how I ought to fix it? I probably have my blinders on.
It's not necessarily a leak, but it is undefined behavior. You created the char array using new[] but the unique_ptr<char> will call delete, and not delete[] to free the memory. Use unique_ptr<char[]> instead.
Also, your conversion may not always behave the way you want it to. You should make 2 calls to wcstombs_s, in the first one pass nullptr as the second argument. This will return the number of characters required in the output string.
wcstombs_s(&charsConverted, nullptr, 0, outputWide, suffix.length());
Check the return value, and then use the result stored in charsConverted to allocate the output buffer.
auto output = std::unique_ptr<char[]>(new char[charsConverted]);
// now use output.get() to get access to the raw pointer

Seg faulting on a car cast from unsigned char to const char in C++

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.

How can I get this += operator to work?

I'm making my own string class and everything is working fine except one this: I'm trying to overload the operator += operator so that I can do this:
string s1 = "Hello", s2 = " World";
s1 += s2;
So this is what I tried:
// In the string class,
string& operator +=(string const& other)
{
using std::strcpy;
unsigned length = size() + other.size() + 1; // this->size() member
char *temp = new char[length]; // function and a "+ 1" for the
// null byte '\0'
strcpy(temp, buffer);
strcpy(temp, other.data());
delete[] buffer;
buffer = new char[length];
strcpy(buffer, temp); // copy temp into buffer
return *this;
}
But in my program I get no output after printing when using the code in main shown above. I also get no errors (not even a runtime error). Why is this and how can I fix this implementation?
Note: I know I can use std::string but I want to learn how to do this myself.
A problem is here:
strcpy(temp, other.data());
You've already copied the first string into the buffer (in the previous line), but this then overwrites it with the other string's data. You want to instead append the other string's data to the buffer using strcat:
strcat(temp, other.data());
As Jerry points out, your other problem is that you're not correctly initialising your strings in the first place.
As an aside, if you're going to use strcpy, strcat, etc, you should really use the length-limited versions (strncpy, strncat) to avoid potential buffer overrun issues.
Just took a quick glance at the demo you posted in the comment under Mac's answer. This is your problem:
string(char const *str) : buffer(new char[strlen(str)]), len(strlen(str))
{}
// ...
string s1 = "Hello";
You're allocating the buffer in the constructor, but never copying the data into it. What happens if you just do std::cout << s1;?
Edit: By the way, I noticed at least two other problems:
You're not updating len in operator +=
Your copy constructor is making two strings point to the same buffer. This is bad, it will blow up when one tries to use it after the other delete[]s it.

C++ Allocated Memory Problem

It has been a long time since I have programmed in C++, but I recently wrote a little C++ function and am having a little bit of trouble. The function returns a struct, Result, that have some strings in it. I thought I allocated memory for the strings, but jsonResult is sometimes partially overwritten.
//The structs
struct Interp {
int score;
char* sentence;
char* jsonResult;
};
struct Result {
int resultCode;
char* errorMessage;
Interp interp;
};
...
//Inside the function
Result result;
//Store decode
const char* jsonResult,* sentence;
if (result.resultCode == -1)
{
LVInterpretation interp = port.GetInterpretation(voiceChannel, 0);
result.interp.score = interp.Score();
sentence = interp.InputSentence();
jsonResult = interp.ResultData().Print(SI_FORMAT_ECMA);
}
//Allocate memory for strings
result.interp.jsonResult = new char[strlen(jsonResult) + 1];
strcpy(result.interp.jsonResult, jsonResult);
result.interp.sentence = new char[strlen(sentence) + 1];
strcpy(result.interp.sentence, sentence);
result.errorMessage = new char[strlen(errorMessage) + 1];
strcpy(result.errorMessage, errorMessage);
return result;
Other info:
I am observing all of this behind the python binding that I wrote, using ctypes. Don't think that is really effecting anything though.
Use std::string. You won't regret it.
I'd put money on your problem being in here:
jsonResult = interp.ResultData().Print(SI_FORMAT_ECMA);
Who 'owns' the char* array returned by Print()? Maybe it's attempting to return a pointer to memory that's out of scope???
example:
char* badFunction(void)
{
char test[100];
strcpy(test,"This is really clever"); // oh, yeah?
return test; // returns pointer to data that's out of scope
}
One other thing. Assign null pointers to sentence, jsonResult, etc when you declare them. Otherwise you could end up strcpy()ing uninitialized data,
Couple of things:
What does "partially overwritten" mean? How do you know this? i.e. what is your expected output vs. what you see?
It's not really clear how result.resultCode is set to -1 (or if it is at all), and if it is set, how does the memory get allocated in interp.InputSentence() and interp.ResultData().Print(SI_FORMAT_ECMA)? I'd suggest that your problem lies there
The rest of the code should work as long as jsonResult and sentence contain valid null terminated strings.