ifstream is crashing on x64 bit platform - c++

i am trying to use ifstream to open a txt file and read data from that file with ifstream, while that code works just fine on x86 bit platform, it causing weird application crash when using it on x64 bit platform.
ifstream font;
font.open(filename);
if ( font.fail() )
{
return false;
}
// Used to read 95 ASCII characters in the text file
for ( int i = 0; i < 95; i++ )
{
font.get(temp);
while (temp != ' ')
{
font.get(temp);
}
font.get(temp);
while (temp != ' ')
{
font.get(temp);
}
font >> m_Font[i].left;
font >> m_Font[i].right;
font >> m_Font[i].size;
}
Removing font.fail() check causes the program to be stuck at font.get(temp); which means that font.fail() is causing the crash of the program, if someone knows a solution to this problem or can point to an alternate way of reading the text file in this context please let me know.
The reproducible example can be found below, make sure to set the build configuration to x64 and subsystem to Windows`
#include <Windows.h>
#include <iostream>
#include <fstream>
using namespace std;
struct TestStruct
{
int test;
}; TestStruct* testStruct;
bool Test(char* filename)
{
testStruct = new TestStruct[8];
if (!testStruct)
{
return false;
}
ifstream font;
font.open(filename);
if (font.fail())
{
return false;
}
char temp;
for ( int i = 0; i < 8; i++)
{
font.get(temp);
while (temp != ' ')
{
font.get(temp);
}
font.get(temp);
while (temp != ' ')
{
font.get(temp);
}
font >> testStruct[i].test;
}
font.close();
return true;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
{
AllocConsole();
freopen("CONOUT$", "w", stdout);
while ( Test((char*)"test.txt") )
{
}
return 0;
}
P.S I am failing to reproduce this issue while executing binary by itself from build folder however it still occurs while launching it with local windows debugger attached.

You have an infinite loop that calls the same function with the same parameter. This function does exactly the same procedure but has a side effect of creating an array of TestStruct.
When everything "goes ok", the function returns true, and is called again. One problem is that you never delete the array you are dynamically creating inside of the function. That means that sooner or later you would run out of memory, and this infinite loop would be broken. But it wouldn't be broken in the way you plan it: the operator new (the one that you are using) would throw an exception (std::bad_alloc) instead of returning nullptr.
That is what I see from your code. The compiler may see the same, and it can optimize the code in many strange ways to achieve the same behavior. Try to correct the issues that cause the UB and memory leaks, and maybe the compiler would change it's mind.

So as some pointed out, casting from one string type to another type, in this case from const char* to char* is causing undefined behavior, at first i fixed it in the reproducible example but couldn't fix it in my main project but after changing all string types to the ones that original function is taking it solved the problem, i.e:
D3DX11CreateShaderResourceViewFromFile is taking LPCTSTR and caused a crash while i was trying to cast LPCTSTR from WCHAR*

Related

Error reading variables: Cannot access memory at adress x

so probably a silly question but i'm not very familiar with C++ so...
Then i run this code, it crash with no error code after hitting the second if in the main
#include <fstream>
#include <string>
#include "day.cpp"
#include "appointement.cpp"
using namespace std;
// Flags are placed as constants to easy access
const string mod="mod", lst="lst", rmv="rmv";
const string add="add", title="-t", date="-d";
bool ispresent (string command, string flag)
{
int pos=command.find(flag);
if (pos==-1)
{
return false;
}
else
{
return true;
}
}
int main()
{
string command;
cout << "Hi, send command:";
//this is analysed and searched for flags
cin >> command;
//if the "add" is present, create a new event (userEvent)
if (ispresent (command, add))
{
cout << "add triggered";
ofstream saveFile;
saveFile.open("/tmp/.calendar/saveFile.txt");
appointement userEvent;
// this test always fail
if (ispresent(command, title))
{
//search for "-t" to add the title to the event
cout << "-t triggered";
int flag=command.find("-t")+2;
cout << "placed after -t";
userEvent.setTitle(command.substr(flag,command.find(" ")));
cout << "title set";
// search for "-d" to add the date to the event
if (command.substr(flag,flag)==date)
{
int flag=flag+2;
userEvent.setTimeNotification(command.substr(flag+2, command.find (" ")));
}
}
}
return 0;
}
at first i thought at a bad test, but running it into gdb given me this error :
ispresent (command=<error reading variable: Cannot access memory at address 0x6a9b6f7a416ff400>,
flag=<error reading variable: Cannot access memory at address 0x3>) at main.cpp:13
I understand that there is something going with access right to the variables but i don't understand what is actually going on...
I check for similar questions here, but nobody seems to explain that is actually going on and how to fix/avoid it in the future
So after #molbdnilo pointed out, my "command" isn't actually the way it thought it was and only contain the first string in the command (each white space breaks my command in multiples strings).
So the issue is then i call the second test, it cannot work because my "command" variable is smaller than the position i tried to test, so then the program call the memory space where the continuation of the variable should be i get an memory error since this program is not allowed to use this memory space.

Lua C API Custom Print function, not called when a space is passed in the string

Problem Description:
I have created a custom C++ function print() that is supposed to be pushed as a global onto a table to so the user can use the print() function to print to the debug console. This function works to some extent, however, when you try to print a string with a space in it (over one word) the function is not called at all... This has greatly confused me, as I don't know why. If I were to try and call something such as print("Hello!") the console will have "Hello!" printed to it, but if I were to try and print something such as print("Hello world!") the function will not be called at all, I know this because I have used a message box to alert when the function is called.
Additional Information:
So, the closest thing to this I could find was a question asking how to make a custom print function in C++ with the Lua C API then push it onto the global table. I can already do this, and my function works to some extent. My function isn't being pushed onto the Lua C API's global table, instead to a table that is created by me with lua_newtable(L, s);. However, I've tried it both ways and it makes no difference. This print function does not support tables nor function as of now, I'm just focused on finding out and fixing why the function can't print strings over one word. Just in case you were wondering, Lua v5.1.5 and Microsoft Visual Studio 2017 are used for this. Debug mode, x86.
Code (C++):
If anyone could help me fix this, that would be great!
#include <iostream>
#include <string>
#include <Windows.h>
#pragma comment(lib, "Lua.lib")
#include "lua.hpp"
#include "luaconf.h"
static int print(lua_State* LUASTATE)
{
MessageBoxA(NULL, "Custom print called.", "FUNCTION!", NULL);
int nargs = lua_gettop(LUASTATE);
std::string string = "";
for (int i = 1; i <= nargs; i++)
{
if (i > 1) string += " ";
switch (lua_type(LUASTATE, i))
{
case LUA_TSTRING:
string += (std::string)lua_tostring(LUASTATE, i);
case LUA_TNUMBER:
string += (int)lua_tonumber(LUASTATE, i);
case LUA_TBOOLEAN:
string += (bool)lua_toboolean(LUASTATE, i);
}
}
std::cout << string << "\n";
return 0;
}
int pushs(lua_State* LuaState)
{
luaL_openlibs(LuaState);
lua_newtable(LuaState);
lua_pushcfunction(LuaState, print);
lua_setglobal(LuaState, "print");
lua_settop(LuaState, 0);
return 0;
}
int main()
{
lua_State* ls = luaL_newstate();
lua_State* LS = lua_newthread(ls);
pushs(LS);
while (true)
{
std::cout << " ";
std::string inputo;
std::cin >> inputo;
luaL_dostring(LS, inputo.c_str());
lua_settop(LS, 0);
}
lua_close(LS);
return 0;
}
Main problem
std::cin >> inputo does not read a full line from the standard input. It just reads a single word. So when you type the following input line in your shell:
print("Hello world")
Your main loop breaks it into two separate strings:
print("Hello
world")
And these string are evaluated independently by the Lua interpreter. None of these strings are valid Lua statements, so the interpreter doesn't execute them. lua_dostring will return an error code, and let an error message on the Lua stack.
To work line by line on the standard input, you can use std::getline, which works well in a loop:
std::string line;
while (std::getline(std::cin, line)) {
// do something with line.
}
Side notes
What follows is not directly related to your bug, but look suspicious:
std::string += int (or bool) interprets the int as a single char, and append this single character to the string.
Your switch/case seems to be missing break statements.
lua_State* ls is never closed.

Change Windows 7 Wallpaper in C++

I saw someone at school who had a program that was supposed to change the background, and log you out (so the change would take effect) but it only worked on his computer, and he "lost" the source code.
I have been looking online for a while for code that would do that, so I could experiment with it.
I found this code (C++)
#include <windows.h>
int main()
{
SystemParametersInfo( SPI_SETDESKWALLPAPER, 0, (PVOID)"image.jpg", SPIF_UPDATEINIFILE );
}
which sort of worked..
It worked twice with an image that was located in the same folder, and I tested two images, and after the second one it just stopped working.
I can't for the life of me figure out why it stopped working (I have tried multiple file extensions, so I know that isn't the issue).
I am working in Dev-C++, if that makes a difference to anyone.
Also, I would like to be able to modify the code to use a url instead of a local image...would that be possible?
Thanks!
Edit: If I change image.jpg to image.bmp it changes every time..But that means that it would only work with *.bmp? I had it working with a jpeg before.
#include <windows.h>
int main()
{
int i;
for(i=0;;i++)
{
Sleep(800);
if(i%2==0)
{
const wchar_t *filenm = L"C:\\Pictures\\image1.jpg"; //ADDRESS of first image
bool isWallSet=SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0,(void*)filenm,SPIF_UPDATEINIFILE);
}
else
{
const wchar_t *filenm = L"C:\\Pictures\\image2.jpg"; //ADDRESS of second image
bool isWallSet=SystemParametersInfoW(SPI_SETDESKWALLPAPER, 0,(void*)filenm,SPIF_UPDATEINIFILE);
}
}
return 0;
}

ifstream fails to open in recursive calls

we are running into an odd issue when trying to parse an input file. the idea is that this file can include other files, which must be parsed as well. We are doing this recursively in a function defined as
int parse_inp(const char* filename)
The main file parses no problem, but recursive calls cannot open their file streams.
int parse_inp(const char* filename)
{
char buffer[BUFFER_MAX+1];
char* token;
std::string tok;
int keywordSection;
bool end_of_file;
int cardNum;
...
int i;
std::string tempop;
double tempd1, tempd2;
SetSegmentCard2 tempSetSegmentCard2;
int offset;
printf("%s\n", filename);
std::ifstream inp;
inp.clear();
inp.open(filename, std::ios::in);
if(!inp.good() || !inp.is_open())
{
char path1[256];
getcwd(path1,256);
printf("CWD: %s\n", path1);
fflush(NULL);
printf("Unable to open '%s'\n", filename);
return 0;
}
std::set<std::string> unrecognized;
std::string line;
while(inp.good() && !inp.eof())
{
getline(inp, line);
strcpy(buffer, line.c_str());
if (isComments(buffer)) //skip the comments line
continue;
if (buffer[0]=='*') //this is a keyword line
{
token = strtok(buffer," \n");
keywordSection = is_inp_keyw(token);
if (keywordSection==0)
unrecognized.insert(token);
cardNum = 0;
continue;
}
//a data line
tempop="";
char* found = NULL;
char path_buffer[100] = "Dyna3DWriter\\";
int pos = 0;
switch(keywordSection)
{
case 0: //not recognized
//end of last keyword, not recognizable word
break;
case 1: //KEYWORD
//"KEYWORD didn't do anything
break;
case 2: //TITLE
break;
case 3: //INCLUDE
token = strtok(buffer, "\n");
inp.clear();
parse_inp(token);
break;
...
}
}
if(inp.is_open())
{
inp.close();
inp.clear();
}
}
The recursive files never parse. I looked around a lot and most issues seemed to be either that the fail bit was set (which is why we are calling inp.clear() a lot), or that we are making the wrong assumption about the current working directory.
To test the second theory, we added in:
if(!inp.good() || !inp.is_open())
{
char path1[256];
getcwd(path1,256);
printf("CWD: %s\n", path1);
fflush(NULL);
printf("Unable to open '%s'\n", filename);
return 0;
}
And our working directory and file name are both correct. We see the same behavior when using fopen(filename, "r") --- a call to perror("fopen") results in:
fopen: no such file or directory
EDIT: Filled in more code
Are you sure the filename does not contain any garbage or bad character that would lead to this issue?
If the error is file not found, that means the filename is wrong in some way.
Could it come from a bad declaration of buffer? We don't see it in your code.
Another possibility is that you use strtok again in your initialization before opening the file. You must avoid using strtok that is based on global storage for recursive method like this. You should use strtok_r instead.
If your recursive function is called very deeply you can easily overload the OS limit on the number of open files.
I used to run my Gentoo Linux with a per-process file limit of 250 with exceptions for programs that needed a lot more.
Windows has limits that vary depending on how much memory is available to the system and how many objects have already been created system-wide.
The smart way to do this is to have two functions. The first function is the one everyone else calls and it does the setup, including opening the file. The second function is the recursive function and it takes nothing but a reference to a std::ifstream object.
EDIT:
I see that I misunderstood your question, and you aren't recursively opening the same file. I will leave my above paragraph anyway.

How to write console data into a text file in C++?

I'm working on a file sharing application in C++. I want to write console output into a separate file and at the same time I want to see the output in console also. Can anybody help me...Thanks in advance.
Here we go...
#include <fstream>
using std::ofstream;
#include <iostream>
using std::cout;
using std::endl;
int main( int argc, char* argv[] )
{
ofstream file( "output.txt" ); // create output file stream to file output.txt
if( !file ) // check stream for error (check if it opened the file correctly)
cout << "error opening file for writing." << endl;
for( int i=0; i<argc; ++i ) // argc contains the number of arguments
{
file << argv[i] << endl; // argv contains the char arrays of commandline arguments
cout << argv[i] << endl;
}
file.close(); // always close a file stream when you're done with it.
return 0;
}
PS: OK, read your question wrong (console output/input mixup), but you still get the idea I think.
The idea is to create a derivate of std::streambuf which will output data to both the file and cout. Then create an instance of it and use cout.rdbuf(...);
Here is the code (tested with MSVC++ 2010, should work on any compiler):
class StreambufDoubler : public std::streambuf {
public:
StreambufDoubler(std::streambuf* buf1, std::streambuf* buf2) :
_buf1(buf1), _buf2(buf2), _buffer(128)
{
assert(_buf1 && _buf2);
setg(0, 0, 0);
setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
}
~StreambufDoubler() {
sync();
}
void imbue(const std::locale& loc) {
_buf1->pubimbue(loc);
_buf2->pubimbue(loc);
}
std::streampos seekpos(std::streampos sp, std::ios_base::openmode which) {
return seekoff(sp, std::ios_base::cur, which);
}
std::streampos seekoff(std::streamoff off, std::ios_base::seekdir way, std::ios_base::openmode which) {
if (which | std::ios_base::in)
throw(std::runtime_error("Can't use this class to read data"));
// which one to return? good question
// anyway seekpos and seekoff should never be called
_buf1->pubseekoff(off, way, which);
return _buf2->pubseekoff(off, way, which);
}
int overflow(int c) {
int retValue = sync() ? EOF : 0;
sputc(c);
return retValue;
}
int sync() {
_buf1->sputn(pbase(), pptr() - pbase());
_buf2->sputn(pbase(), pptr() - pbase());
setp(_buffer.data(), _buffer.data(), _buffer.data() + _buffer.size());
return _buf1->pubsync() | _buf2->pubsync();
}
private:
std::streambuf* _buf1;
std::streambuf* _buf2;
std::vector<char> _buffer;
};
int main() {
std::ofstream myFile("file.txt");
StreambufDoubler doubler(std::cout.rdbuf(), myFile.rdbuf());
std::cout.rdbuf(&doubler);
// your code here
return 0;
}
However note that a better implementation would use templates, a list of streambufs instead of just two, etc. but I wanted to keep it as simple as possible.
What you want actually is to follow in real time the lines added to the log your application writes.
In the Unix world, there's a simple tool that has that very function, it's called tail.
Call tail -f your_file and you will see the file contents appearing in almost real time in the console.
Unfortunately, tail is not a standard tool in Windows (which I suppose you're using, according to your question's tags).
It can however be found in the GnuWin32 package, as well as MSYS.
There are also several native tools for Windows with the same functionality, I'm personally using Tail For Win32, which is licensed under the GPL.
So, to conclude, I think your program should not output the same data to different streams, as it might slow it down without real benefits, while there are established tools that have been designed specifically to solve that problem, without the need to develop anything.
i don't program in c++ but here is my advice: create new class, that takes InputStream (istream in c++ or smth), and than every incoming byte it will transfer in std.out and in file.
I am sure there is a way to change standard output stream with forementioned class. As i remember, std.out is some kind of property of cout.
And again, i spent 1 week on c++ more than half a year ago, so there is a chance that all i've said is garbage.