EDIT: Well...that's very interesting. I made settings into a pointer and passed that. Worked beautifully. So, this is solved. I'll leave it open for anyone curious to the answer.
I'm having an issue creating a sound in FMod from a memory stream. I looked at the loadfrommemory example shipped with FMod and followed that. First, the code I'm using...
CSFX::CSFX(CFileData *fileData)
{
FMOD_RESULT result;
FMOD_CREATESOUNDEXINFO settings;
settings.cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
settings.length = fileData->getSize();
_Sound = 0;
std::string temp = "";
for (int i = 0; i < fileData->getSize(); i++)
temp += fileData->getData()[i];
result = tempSys->createSound(temp.c_str(), FMOD_SOFTWARE | FMOD_OPENMEMORY, &settings, &_Sound);
}
As it is like this, I get an access violation on tempSys->createSound(). I've confirmed that tempSys is valid as it works when creating sounds from a file. I've also confirmed the char * with my data is valid by writing the contents to a file, which I was then able to open in Media Player. I have a feeling there's a problem with settings. If I change that parameter to 0, the program doesn't blow up and I end up with result = FMOD_ERR_INVALID_HANDLE (which makes sense considering the 3rd parameter is 0). Any idea what I'm doing wrong?
Also, please disregard the use of std::string, I was using it for some testing purposes.
Solved by turning settings into a pointer. See code below:
CSFX::CSFX(CFileData *fileData)
{
FMOD_RESULT result;
FMOD_CREATESOUNDEXINFO * settings;
_Sound = 0;
std::string temp = "";
for (int i = 0; i < fileData->getSize(); i++)
temp += fileData->getData()[i];
settings = new FMOD_CREATESOUNDEXINFO();
settings->cbsize = sizeof(FMOD_CREATESOUNDEXINFO);
settings->length = fileData->getSize();
result = tempSys->createSound(temp.c_str(), FMOD_SOFTWARE | FMOD_OPENMEMORY, settings, &_Sound);
delete settings;
settings = 0;
}
You need to memset settings before using it.
memset(&settings, 0, sizeof(FMOD_CREATESOUNDEXINFO);
Otherwise it will contain garbage and potentially crash.
Related
I am trying to make a function that converts a TCHAR array to individual arrays, splitting it by a comma, then add a null terminator character (I think that is the name, it is '\0' in regEx). (Basically, the .split function in java, + a '\0'), but the code is only adding one value, then stops. It is very weird, as I believe this worked ~3-4 months ago, but not now for a reason unknown.
I would imagine it is an issue with my conceptual understanding of C++, as it is very much not my language of choice.
My apologies that this is basically asking someone to "fix my homework" (not actually homework, just a side project). However, I can't find the issue and have been unable to find the error for a few hours now, again probably due to me being dumb with C++.
Code Sample:
TCHAR** schemeValueToArray(TCHAR* buffer, DWORD size) {
TCHAR delim = ',';
TCHAR** out = new TCHAR*[CURSORS_AMOUNT];
int lastSeperator = 0;
for (int outOn = 0; outOn < CURSORS_AMOUNT-1; outOn++) {
// Get rest of section until end
TCHAR* temp = new TCHAR[size];
for (int i = 0; i < size; i++) {
if (buffer[i + lastSeperator] == ',') {
temp[i] = '\0';
out[outOn] = temp;
lastSeperator += i;
lastSeperator++;
break;
}
temp[i] = buffer[i + lastSeperator];
}
}
return out;
}
If you would like a bigger snippet, I can provide it.
Also, if it helps, this project once would change my mouse cursor theme when an app called AutoDarkMode requested. Making my cursor light theme during the day and dark theme at night. It would do this by copying the Registry theme value, splitting it, then putting the correct files in the correct registry spots. It was a small thing that I really liked, and now in explicitly, it has stopped.
Also, also, I am a lot more familiar with Java and Kotlin. If you are looking for ways to describe something and can relate it to something in those languages, I should be able to understand.
Thank you guys, appreciate any help!
If at all possible, I'd switch to using something like an std::vector<std::string> instead of pointers to pointers and such.
std::vector<std::string> schemeValueToArray(TCHAR* buffer) {
std::istringstream buf(buffer);
std::vector<std::string> ret;
std::string item;
while (std::getline(buf, item, ',')) {
ret.push_back(item);
}
return ret;
}
So first all I'll preface this with: I just started using c++.
I have a structure that I store the pointer to in an unordered_map, setting members' values in the struct pointer as I get them through my process. Then I no longer need them in a map so I transfer then to a vector and loop through them.
Though on the second loop, it outputs my index (1) but the next statement of making a local pointer var for the struct at that index breaks it and the code terminates without any errors. since there are no errors then a try/catch doesn't give me anything either.
// Wanted to create a structure to handle the objects easier instead
// of multiple vectors for each property
struct appData {
std::string id = "";
std::string name = "";
std::string vdf_file = "";
std::string vdf_path = "";
};
// Relevant parts of my main()
int main() {
// Map that stores all the struct pointers
std::unordered_map<std::string, appData*> appDatas;
char memory[sizeof(appData)];
void* p = memory;
// New instance of appData
appData *tempAppData = new(p) appData();
tempAppData->appid = "86901";
// Add tempAppData to map with string key
appDatas["86901"] = tempAppData;
...
std::vector<appData*> unhashed_appDatas;
for (auto const& pair: appDatas) {
unhashed_appDatas.push_back(pair.second);
}
...
for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
// Output index to see where it was messing up
std::cout << x << std::endl;
!! // This is where the issue happens on the second loop (see output)
appData *thisAppData = unhashed_appDatas[x];
std::string id = thisAppData->appid;
std::cout << id << std::endl;
/* ...
Do more stuff below
*/
}
...
return 0;
}
Terminal Output:
0 // Initial index of x
86901 // Id of first item
1 // New index of x on second loop before pointer var is created
// Nothing more is printed and execution terminates with no errors
My knowledge of c++ is pretty lacking, started it couple days ago, so the few things within my knowledge I've tried: moving the *thisAppData variable outside of the loop, using a for(var: vector) { ... }, and a while loop. I can assume that the issue lies with the pointer and the local variable when inside the loop.
Any help/input about how I could better approach this or if there's an issue with my code would be appreciated :)
Edit: Changed code to use .size() instead of sizeof() per #Jarod42 answer, though main issue persists
Edit2: Turns out it was my own mess-up, imagine that. 4Am brain wasn't working too well- posted answer regarding what I did incorrectly. Thanks to everyone who helped me
sizeof is the wrong tool here:
for (unsigned int x = 0; x < sizeof(unhashed_appDatas); x++) {
// ^^ wrong: give **static** size of the structure
// mainly 3 members (data, capacity, size), so something like `3*sizeof(void*)`
it should be
for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
After many hours of trial and error I have determined the issue (aside from doing things in a way I should, which I've since corrected) it was something I messed up on that caused this issue.
TLDR:
Items wouldn't exist that I assumed did and tried to read files with a blank path and parse the contents that didn't exist.
Explaination:
In the first loop, the data I was getting was a list of files from a directory then parsing a json-like file that contained these file names and properties associated with them. Though, the file list contained entries that weren't in this other data file (since I had no check if they existed) so it would break there.
Additionally in the last loop I would get a member from a struct that would be the path of a file to read, but it would be blank (unset) because it didn't exist in data file so std::ifstream file(path); would break it.
I've since implemented checks for each key and value to ensure it will no longer break because of that.
Fixes:
Here are some fixes that were mentioned that I added to the code, which did help it work correctly in the end even if they weren't the main issue that I myself caused:
// Thanks to #EOF:
// No longer "using placement new on a buffer with automatic storage duration"
// (whatever that means haha) and was changed from:
char memory[sizeof(appData)];
void* p = memory;
appData *tempAppData = new(p) appData();
// To:
appData *tempAppData = new appData();
// Thanks to #Jarod42:
// Last for loop limit expression was corrected from:
for (unsigned int x = 0; x < sizeof(unhashed_appDatas); x++) {
}
// To:
for (unsigned int x = 0; x < unhashed_appDatas.size(); x++) {
}
// I am still using a map, despite comment noting to just use vectors
// (which I could have, but just would prefer using maps):
std::unordered_map<std::string, appData*> appDatas;
// Instead of doing something like this instead (would have arguably have been easier):
std::vector<std::string> dataKeys = { "1234" };
std::vector<appData*> appDatas = { ... };
auto indx = find(dataKeys.begin(), dataKeys.end(), "1234");
indx = (indx != dataKeys.end() ? indx : -1);
if (indx == -1) continue;
auto dataItem = appDatas[indx];
//
I appreciate everyone's assistance with my code
Recently VS17 started giving me the "Incremental Linker has stopped working" a lot, and I mean A LOT. I did not update anything (OS or VS). It started out of a sudden for no apparent reason. Most of the time I managed to change my code so it wouldn't happen.
This is my current code (it's supposed to XOR a string and return hex escaped string):
__inline char* EncryptString(const char* String, const char* Key)
{
char* szEncrypted = new char[lstrlenA(String) + 1];
memcpy(szEncrypted, String, lstrlenA(String));
for (int32_t i = 0; i < lstrlenA(String); ++i)
szEncrypted[i] = String[i] ^ Key[i % (sizeof(Key) / sizeof(char))];
std::stringstream lpStream;
for (int32_t i = 0; i < lstrlenA(szEncrypted); ++i)
{
char cCharInd = szEncrypted[i];
int32_t nCharNum = static_cast<int32_t>(cCharInd);
lpStream << "\\x" << 2;
}
std::string sHexEscaped = lpStream.str();
lpStream.clear();
delete[] szEncrypted;
char* szReturn = new char[sHexEscaped.length() + 1];
memcpy(szReturn, sHexEscaped.c_str(), sHexEscaped.length() + 1);
return szReturn;
}
Is any hotfix coming? Or maybe you know what in my code caused this? (Yes, I am deleting the returned char*. Not that it has anything to do with the linker error but don't bully me because of it).
Or is anyone else experiencing this in VS17?
Thanks mate, it works. You can make it an answer if you want and I'll
accept it
It seems that it might be some sort of bug in VS2017. This kind of linker error happened to me even with relatively small code and something as simple as changing the output value of std::cout would trigger it for example. The solution seems to be to run Clean action on the code, which could be found in
Solution Explorer -> [Right Click on the project name] -> Clean
I have a problem with my code. I want to show different windows one by one by clicking the "Next" button to show the next one like this:
int i = 0;
do {
auto polyLines = new ExportPolyLines(nodeNames);
polyLines->show();
if (!polyLines->isVisible()) {
i++;
}
} while (i < 3);
The code compiled but did not work!
Can anyone help me about this?
As an improvement to your comment I would suggest that you fix the memory leak.
if (_logIsSelected)
{
for (int i = 0; i < _selectedWellLogs.size(); i++)
{
auto exportLogsData = new ExportsLogs(_selectedWellLogs[i], _wellLogsName[i], _folder);
exportLogsData->exec();
delete exportLogsData; // Free the memory that has been used for ExportLogs
exportLogsData = nullptr; // Not really necessary here, but good practice
}
}
As stated above my program works in Debug and Release without debug (ctrl + F5) however does not work in simply Release.
Just to clarify I have already checked to see if I have some uninitialized variables and I haven't (to the best of my knowledge anyway but I have spent quite some time looking).
I believe to have localized the issue and what I have come across is, in my opinion, very bizarre. First I set up the break points as shown in the picture below:
Then I run the program in release. And instantly the top break point moves:
I found this extremely odd. Now note the number 6302 assigned to 'n'. This number is correct and what I hoped to pass through. Now watch as I continue through the program.
We are still in good shape but then it turns for the worst.
'n' changes to 1178521344, which messes up the rest of my code.
Would someone be able to shed some light on the situation, and even better, offer a solution.
Thanks,
Kevin
Here is the rest of the function if it helps:
NofArr = n;
const int NA = n;
const int NAless = n-1;
double k_0 = (2*PI) / wavelength;
double *E = new double[NAless]; // array to hold the off-diagonal entries
double *D = new double[NA]; // array to hold the diagonal entries on input and eigenvalues on output
int sizeofeach = 0;
trisolver Eigen;
int* start; int* end;
vector< vector<complex <double>> > thebreakup = BreakUp(refidx, posandwidth, start, end);
for(int j = 0; j < (int)thebreakup.size(); j++){
// load the diagonal entries to D
for(int i =0; i < (int)thebreakup[j].size(); i++){
D[i] = -((double)2.0/(dx*dx)) + (k_0*k_0*thebreakup[j][i].real()*thebreakup[j][i].real());
}
// load the off diagonal
for(int i = 0; i < (int)thebreakup[j].size(); i++){
E[i] = (double)1.0 / (dx*dx);
}
sizeofeach = (int)thebreakup[j].size();
double *arr1= new double[sizeofeach];
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
complex <double> tmp( PhaseAndAmp[j][1]*cos(PhaseAndAmp[j][0]), PhaseAndAmp[j][1]*sin(PhaseAndAmp[j][0]));
// rebuild the break up with the mode
for(int i = 0; i < (int)thebreakup[j].size(); i++){
thebreakup[j][i] = (complex<double>(arr1[i],0.0)) * tmp ;
}
delete []arr1;
}
vector<complex<double>> sol = rebuild(thebreakup, start, end);
delete [] E;
delete [] D;
delete [] start;
delete [] end;
return sol;
I'm writing this as an answer, because it's way harder to write as a comment.
What strikes me immediately is the array "arr1"
First you allocate new memory and store a pointer to it in the variable arr1
double *arr1= new double[sizeofeach];
Then, immediately, you overwrite the address.
arr1 = Eigen.EigenSolve(E, D, sizeofeach, mode);
Later, you delete something. Is it safe?
delete []arr1;
It's not the double array you allocated, but something eigensolve returned. Are you sure you have the right to delete it? Try removing the delete here. Also, fix the memory leak too, by removing allocation in the first line I gave.
What worries me even more is that the "this" pointer changes. There is some nasty problem somewhere. At this point, your program has already been corrupted. Look for the issue somewhere else. Valgrind would be a GREAT tool if you can try to compile under linux.
It seems that there is some sort of code optimization going on in your program. It is not always easy to debug optimized code step-by-step since the optimization may reorder instructions.
I cannot see why the fact that 'n' changes to an apparently uninitialized value would be the root cause of the problem, since 'n' is anyways no longer used in your function. Seems like the memory is simply been released as part of the optimization.
I have discovered my mistake. Earlier in the program I was comparing pointers, not what they were pointing at. A stupid mistake but one I wouldn't have spotted without a long debugging session. My boss explained that the information given at the bottom of Visual Studio whilst in release mode cannot be trusted. So to "debug" I had to use std::cout and check variables that way.
So here is the mistake in the code:
if(start > end){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}
Where start and end were defined earlier as:
int* start = new int[NofStacks];
int* end = new int[NofStacks];
And initialized.
Thanks to all those who helped and I feel I must apologise for the stupid error.
The Fix being:
if(start[i] > end[i]){
int tmp = start[i];
start[i] = end[i];
end[i] = tmp;
}