I have a large file, about 4GB. I need to read a portion of that file that is bigger than INT32_MAX. std::ifstream::read() accepts a std::streamsize as second input (number of bytes to read). Since I'm on 64 bit, that is a typedef to ptrdiff_t which should be a int64_t.
So I would expect to be able to read 9223372036854775807 at once. My example below proves me wrong. The failbit is set when I read more than INT32_MAX.
What am I missing?
#include <fstream>
#include <iostream>
#include <limits>
int main() {
std::cout << "Maximum of std::streamsize: "
<< std::numeric_limits<std::streamsize>::max() << std::endl;
std::cout << "INT32_MAX: " << std::numeric_limits<int32_t>::max()
<< std::endl;
auto const filename = R"(C:\TEMP\test.dat)"; // a large file > INT32_MAX
auto dataStream = std::ifstream();
dataStream.open(filename, std::ios_base::binary);
dataStream.seekg(0, dataStream.end);
size_t filesize = dataStream.tellg();
std::cout << "Size of file: " << filesize << std::endl;
// buffer for the whole file
auto buffer = new uint8_t[filesize];
dataStream.seekg(0, dataStream.beg);
std::cout << "Reading INT32_MAX bytes..." << std::endl;
dataStream.read(reinterpret_cast<char*>(buffer),
std::numeric_limits<int32_t>::max());
std::cout << "Read failed: " << dataStream.fail() << std::endl;
dataStream.seekg(0, dataStream.beg);
std::cout << "Reading INT32_MAX + 1 bytes..." << std::endl;
dataStream.read(
reinterpret_cast<char*>(buffer),
static_cast<int64_t>(std::numeric_limits<int32_t>::max()) + 1);
std::cout << "Read failed: " << dataStream.fail() << std::endl;
delete[] buffer;
}
I compiled with:
$ g++ --version
g++.exe (Rev2, Built by MSYS2 project) 9.2.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
On a Windows 7 Laptop gives:
Maximum of std::streamsize: 9223372036854775807
INT32_MAX: 2147483647
Size of file: 4001202702
Reading INT32_MAX bytes...
Read failed: 0
Reading INT32_MAX + 1 bytes...
Read failed: 1
I worked around this issue by reading multiple INT32_MAX sized chunks. I'm interested to know why this failed though.
EDIT: I did some more testing. compiled on Linux with GCC 8.3: works, compiled with MSVC15: works.
So I guess there's a problem with the libstdc++ that comes with MinGW-W64.
EDIT2: Problem still exists with
$ gcc --version
gcc.exe (Rev8, Built by MSYS2 project) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
can you try this
auto buffer = new int32_t[filesize];
Related
This is a clip of my code
void start_hang(){
cout << "*********************\n";
cout << " \n";
cout << " \n";
cout << " \n";
cout << " \n";
cout << " \n";
cout << " \n";
cout << "*********************\n";
cout << "=====================\n";
}
But here is my output
*********************
*********************=====================
Here is my other attempt to make it work:
Not using namespace
Put std:: in front of every output
void start_hang(){
std::cout << "*********************\n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << "*********************\n";
std::cout << "=====================\n";
}
And still does not work.
Maybe I'm using class wrong?
Here is my full code:
https://pastebin.com/AmfZErqS
Here is my compiler:
g++ (tdm64-1) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
The code is correct and there's no issue with it. The issue lies in the way you're compiling and executing.
On UNIX-like systems, the default name for the output binary from gcc is a.out (which is also an ancient executable format)
-o file
Place the primary output in file file. This applies to whatever sort of output is being produced, whether it be an executable file, an object file, an assembler file or preprocessed C code.
If -o is not specified, the default is to put an executable file in a.out, the object file for source.suffix in source.o, its assembler file in source.s, a precompiled header file in source.suffix.gch, and all preprocessed C source on standard output.
https://gcc.gnu.org/onlinedocs/gcc/Overall-Options.html
On Windows it's a.exe by default. You must specify the name using the -o option, or you'll have to run a.exe. So if you compile with g++ game.cpp then run game.exe then you're executing some old buggy game.exe compiled before
See Why does my GCC compiler not compile C code?
Im compiling with g++ game.cpp which resulting to the error hmm
however , after i do g++ -g game.cpp -o game.exe , it gives an output and and the program works as it supposed to be
For some strange reason std::this_thread::sleep_for does not work for me on WSL Ubuntu. It just refuses to sleep for the indicated time. I would like a second opinion to find out if I'm doing something wrong or if I just hit a bug in GNU C++ std:: implementation.
USER#ABC-WORKSTATION /tmp
$ cat sleep_test.cpp
#include <chrono>
#include <thread>
#include <iostream>
int main()
{
auto start = std::chrono::system_clock::now();
std::time_t start_time = std::chrono::system_clock::to_time_t(start);
std::cout << "Start: " << std::ctime(&start_time) << std::endl;
std::cout << "Sleep... " << std::endl;
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
auto end = std::chrono::system_clock::now();
std::time_t end_time = std::chrono::system_clock::to_time_t(end);
std::cout << "End: " << std::ctime(&end_time) << std::endl;
}
USER#ABC-WORKSTATION /tmp
$ g++ --version
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
Copyright (C) 2019 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
USER#ABC-WORKSTATION /tmp
$ g++ -o sleep_test sleep_test.cpp
USER#ABC-WORKSTATION /tmp
$ sleep_test
Start: Wed Sep 9 14:15:18 2020
Sleep...
End: Wed Sep 9 14:15:18 2020
USER#ABC-WORKSTATION /tmp
$
As shown above, there was no 10000 msec sleep, and the code executed instantaneously!
The following code tries to rename an existing file to a new location. In my environment, the rename fails because source and destination are on different mount points.
Given the failure, why is the value of errno reported as 0 in version2()? I can't imagine errno not being set synchronously with rename(), and I imagined that operands to std::ostream::operator<< were evaluated in left-to-right order. If that were true, shouldn't errno have acquired its nonzero value from rename's failure before it was passed to the output operator?
Obviously reality is not matching what I imagined; can someone explain the order of evaluation or other relevant reasons why version2 outputs an errno value of 0?
The code:
// main.cpp
// Prereq: "./" and "/tmp" are on different mount points.
// Prereq: "./foo.txt" exists.
#include <cstdio>
#include <iostream>
#include <cerrno>
#include <cstring>
void version1()
{
std::cout << __FUNCTION__ << std::endl;
std::cout << rename( "./foo.txt", "/tmp/bar.txt" ) << std::endl;
std::cout << errno << ": " << strerror( errno ) << std::endl;
}
void version2()
{
std::cout << __FUNCTION__ << std::endl;
std::cout << rename( "./foo.txt", "/tmp/bar.txt" ) << ": "
<< errno << ": " << strerror( errno ) << std::endl;
}
int main( int argc, char* argv[] )
{
errno = 0;
version1();
errno = 0;
version2();
return 0;
}
Compilation & output:
> g++ --version && g++ -g main.cpp && ./a.out
g++ (GCC) 4.8.3 20140911 (Red Hat 4.8.3-7)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
version1
-1
18: Invalid cross-device link
version2
-1: 0: Success
(I searched SO for existing questions addressing this, but either none exist, or my search phrasings weren't adequate matches for anything existing)
Update:
I think this question resolves down to "what is the order of evaluation of the operands to the output operator?" in which case, according to Order of evaluation of arguments using std::cout the answer is "unspecified."
In the spirit of academic learning (and generating information useful to the community), I'm curious if anyone is aware of the history why the order of evaluation of output stream operands is undefined: It seems intuitive that they should be evaluated left-to-right...?
I just installed the Boost library and I am trying to get through the basic tutorial.
I am trying to open a process that runs g++ --version and pipes the output to std_std_out.
The code is copied from the tutorial with the following changes:
added cout statements to track progress
added call to bp::find_executable_in_path()
Here's the code:
//
// Boost.Process
// ~~~~~~~~~~~~~
//
// Copyright (c) 2006, 2007 Julio M. Merino Vidal
// Copyright (c) 2008 Boris Schaeling
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
//
#include <boost/process.hpp>
#include <string>
#include <vector>
#include <iostream>
namespace bp = ::boost::process;
using namespace std;
bp::child start_child() {
string exec = bp::find_executable_in_path( "g++" );
cout << "full path is " << exec << endl;
cout << "starting child process" << endl;
vector<std::string> args;
args.push_back( "--version" );
bp::context ctx;
ctx.stdout_behavior = bp::capture_stream();
ctx.stderr_behavior = bp::capture_stream();
return bp::launch( exec, args, ctx );
}
int main() {
bp::child c = start_child();
bp::pistream &is = c.get_stdout();
cout << ( is ? "stream is valid" : "stream is NOT valid" ) << endl;
string line;
cout << "entering read/write loop" << endl;
while( getline( is, line ) ) {
cout << "copying a line" << endl;
cout << line << endl;
}
cout << "exiting read/write loop" << endl;
}
Here is what I see when I run g++ --version on the command line:
g++ (GCC) 4.8.5 20150623 (Red Hat 4.8.5-11)
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This is the output of the compiled program:
full path is /usr/bin/g++
starting child process
stream is valid
entering read/write loop
exiting read/write loop
It never enters the read/write loop. What happened to the data from the stream?
You need to enter the full path to gcc, or use bp::find_executable_in_path("g++")
[edit] oops. Under windows:
bp::find_executable_in_path("g++.exe")
I am just using the example code from the mysql site. This program will compile and run if I do it in debug. If I compile in release it gives me the error in the title. I downloaded all the connectors and server from oracle site, so everything is up to date on my end. I even compiled both the latest releases of c++ connectors and c connectors. I have done a lot of searches on this and tried what they said to do, but could not fix this. My lib and dll files from what I have seen have the mysql_get_option function listed. I made sure there are no stray dll or lib files on my computer. I checked the system path variable to make sure it wasnt pointing in some random area. I am using Vs2013.
Please help I have tried to fix this for a week and my brain is about to explode!! Thank you for any advice.
P.S.
I program as a hobby so it is more than likely I am overlooking something trivial.
/* Copyright 2008, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.
There are special exceptions to the terms and conditions of the GPL
as it is applied to this software. View the full text of the
exception in file EXCEPTIONS-CONNECTOR-C++ in the directory of this
software distribution.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Standard C++ includes */
#include <stdlib.h>
#include <iostream>
/*
Include directly the different
headers from cppconn/ and mysql_driver.h + mysql_util.h
(and mysql_connection.h). This will reduce your build time!
*/
#include "mysql_connection.h"
#include <cppconn/driver.h>
#include <cppconn/exception.h>
#include <cppconn/resultset.h>
#include <cppconn/statement.h>
using namespace std;
int main(void)
{
cout << endl;
cout << "Running 'SELECT 'Hello World0000........ AS _message'..." << endl;
try {
sql::Driver *driver;
sql::Connection *con;
sql::Statement *stmt;
sql::ResultSet *res;
/* Create a connection */
driver = get_driver_instance();
con = driver->connect("*****", "*****", "*****");
/* Connect to the MySQL test database */
//con->setReadOnly(true);
con->setSchema(*****);
cout << "\nHere!";
stmt = con->createStatement();
res = stmt->executeQuery("SELECT DISTINCT eqdkp10_raid_attendees.raid_id, eqdkp10_raids.raid_value \
FROM eqdkp10_raids LEFT JOIN eqdkp10_raid_attendees ON eqdkp10_raids.raid_id \
= eqdkp10_raid_attendees.raid_id AND eqdkp10_raid_attendees.member_id=2");
while(res->next()) {
cout << "\t... MySQL replies: ";
/* Access column data by alias or column name */
cout << res->getString("_message") << endl;
cout << "\t... MySQL says it again: ";
/* Access column fata by numeric offset, 1 is the first column */
cout << res->getString(1) << endl;
}
delete res;
delete stmt;
delete con;
}
catch(sql::SQLException &e) {
cout << "# ERR: SQLException in " << __FILE__;
cout << "(" << __FUNCTION__ << ") on line " << __LINE__ << endl;
cout << "# ERR: " << e.what();
cout << " (MySQL error code: " << e.getErrorCode();
cout << ", SQLState: " << e.getSQLState() << " )" << endl;
}
cout << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
I googled your post title and found this link: http://www.linuxtalks.net/mysql-community-server-5-7-4-m14-has-been-released/
If your search the page for mysql_get_option you will see they fixed this known bug. If you're using VS2013 your library version might include this bug since the page refers to a release in 2014.