pointer not being updated when passed between functions - c++

So my main function looks like this:
void main {
uint32 errmsg;
uint32 mydata;
if (LOG) {
std::ofstream file;
file.open(fileName,ios_base::app);
file << "!!!mydata: " << mydata << ",&mydata: " << &mydata << endl;
file.close();
}
errmsg = ReadReg32(0, 0, &mydata);
if (LOG) {
std::ofstream file;
file.open(fileName,ios_base::app);
file << "!!! returned mydata: " << mydata << ",&mydata: " << &mydata << endl;
file.close();
}
}
and calls ReadReg32 below:
static uint32 ReadReg32(uint32 brdNum, uint32 address, uint32 *data)
{
std::ofstream file;
if (LOG) {
file.open(fileName,ios_base::app);
file << " ReadReg32: brdNum =" << brdNum << ", address =" << address << endl;
file << " ReadReg32 ... Data WAS: " << *data << endl;
file.close();
}
/* AD:TW Check if we need to do init */
bool initstatus = checkDeferredInit();
ADMXRC3_HANDLE phCard;
ADMXRC3_STATUS status;
//open card
if((status = ADMXRC3_Open(brdNum, &phCard)) != ADMXRC3_SUCCESS)
return status;
//read data
if((status = ADMXRC3_Read(phCard, NON_PREFETCHABLE_SPACE, 0, address, 4, &data)) != ADMXRC3_SUCCESS){
ADMXRC3_Close(phCard);
return status;
}
if (LOG) {
file.open(fileName,ios_base::app);
file << " ReadReg32 ... Data IS: " << data << ", &data: " << &data << ", Read status =" << status << endl;
file.close();
}
//close card
status = ADMXRC3_Close(phCard);
if (LOG) {
file.open(fileName,ios_base::app);
file << " ReadReg32 ... Close card status =" << status << ", Returning ..." << endl;
file.close();
}
return status;
}
The relevant output is this:
!!!mydata: 348,&mydata: 000000000012F050
ReadReg32: brdNum =0, address =0
ReadReg32 ... Data WAS: 348
checkDeferredInit
ReadReg32 ... Data IS: 0000000081040102, &data: 000000000012EF30, Read status =0
ReadReg32 ... Close card status =0, Returning ...
!!! returned mydata: 348,&mydata: 000000000012F050
where 0000000081040102 is the correct number i expect to see, but it never returns that to the calling function, i.e. mydata is never updated.
Interesting notes:
in ADMXRC3_Read, if I don't use &data, i get "incorrect" data values
in ADMXRC3_Read, the type for where i'm sticking in &data is
supposed to be void *pbuffer?
Any thoughts are worth like a case of beer, or a moderately fine boxed wine. ;)
I do appreciate any thoughts you have, this has me stumped...

Well at first glance it seems you are using & too much.
static uint32 ReadReg32(uint32 brdNum, uint32 address, uint32 *data)
{
....
//read data
if((status = ADMXRC3_Read(phCard, NON_PREFETCHABLE_SPACE, 0, address, 4, &data)) != ADMXRC3_SUCCESS){
ADMXRC3_Close(phCard);
return status;
}
Here in read data part, you are calling ADMXRC3_Read with &data param. But data is already pointer! So you actually pass adress of variable that is local to your function.
To fix this, call the ADMXRC3_Read with data only.
IMPORTANT: In C and C++ everything is passed by value! So the data is just an variable holding 32-bit number (if you have 32bit addresses), nothing more.
EDIT: In my note I was referring to this FAQ: http://c-faq.com/ptrs/passbyref.html and I wrote it wrong. See the FAQ for more info.

Related

Add multiple files from buffers to ZIP archive using libzip

I'm trying to use libzip in a program that needs to archive several data chunks in different files. At the moment I have a code similar to the following snippet, edited from in-memory.c example in libzip examples.
The zip file is correctly saved with the files inside, but each file contains garbage.
Any help is appreciated.
bool push_files(zip_t* za) {
for (int i = 0; i < 10; i++) {
// Generate data
std::stringstream ss;
ss << "Test file #" << i;
std::string a = ss.str();
zip_source_t* source = zip_source_buffer(za, a.c_str(), a.size(), 0);
if (source == NULL) {
std::cerr << "error creating source: " << zip_strerror(za) << std::endl;
return false;
}
// Add buffer with filename
std::stringstream fname;
fname << "TEST-" << i;
a = fname.str();
if (zip_file_add(za, a.c_str(), source, ZIP_FL_ENC_UTF_8) < 0) {
std::cerr << "error adding source: " << zip_strerror(za) << std::endl;
return false;
}
}
return true;
}
int main() {
zip_source_t* src;
zip_error_t error;
zip_t* za;
zip_error_init(&error);
if ((src = zip_source_buffer_create(NULL, 0, 1, &error)) == NULL) {
std::cerr << "can't create source: " << zip_error_strerror(&error) << std::endl;
zip_error_fini(&error);
return 1;
}
if ((za = zip_open_from_source(src, ZIP_TRUNCATE, &error)) == NULL) {
std::cerr << "can't open zip from source: " << zip_error_strerror(&error) << std::endl;
zip_source_free(src);
zip_error_fini(&error);
return 1;
}
zip_error_fini(&error);
zip_source_keep(src);
if (!push_files(za))
return -1;
if (zip_close(za) < 0) {
std::cerr << "can't close zip archive" << zip_strerror(za) << std::endl;
return 1;
}
// ... omissis, save archive to file as in in-memory.c
}
zip_source_buffer does not copy the data out of the buffer - it just creates a zip_source_t which points to the same buffer. So you must keep the buffer alive until you're done adding the file.
Your code does not keep the buffer alive. The buffer you use is a.c_str() which is the data buffer of the string a. Fair enough, so far. But then before adding the file, you reassign the variable a = fname.str(); which (probably) frees that buffer and allocates a new one.
Solution: use a separate variable for the filename. Don't overwrite a until the file has been added.

Simple ReadProcessMemory not working

I googled a bit but can't seem to make this work.
privileges();
int pid = getPid("test.exe");
cout << "Process ID :" << pid << endl;
const char* prename;
HANDLE pHandle = OpenProcess(PROCESS_VM_READ , FALSE, pid);
if (pHandle)
{
cout << "Handle Open Success" << endl;
//SIZE_T bytesRead;
if (ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, strlen(prename), NULL))
{
cout << "Read Success" << endl;
cout << prename << endl;
}
else
cout << GetLastError() << endl;
}
return 0;
It prints "Read Success" but does not print the variable just blank. The address(address of a string in another process) I got is from ollydbg and verified it using a function as well.
I also wanted to replace the string using writeprocessmemory but before i get to that i needed to make sure reading is correct.
Any idea?
Your problem lies here:
const char* prename;
ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, strlen(prename), NULL)
Your char pointer is not initialized and neither is the random memory it points to. When you call strlen on it, it's trying to get the length of a random memory location.
Secondly you're using the address of the pointer &prename, that's the address of the pointer not the char array it should point to.
To fix do it like this:
char prename[100];
ReadProcessMemory(pHandle, (void*)0x013831BC, &prename, sizeof(prename), NULL)
sizeof() will return 100, so you will be reading 100 bytes of memory

Fuse C++ driver - read() implementation

I'm trying to implement a FUSE driver.
What I've done, is taken the basic operations that you override with your own function, and I've added a cout << operation << path << endl; So I can see which operation gets called. Here is my open function:
int Router::open(const char *path, struct fuse_file_info *fi) {
std::cout << "open " << path << std::endl;
return 0;
}
This returns 0 so the open should succeed all the time.
Then, here is my read function:
int Router::read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) {
std::cout << "read " << path << "Size: " << size << "Offset: " << offset << std::endl;
buf[0] = 'h';
buf[1] = '\0';
return 2;
}
This should copy over h\0 to the buffer.
But when I do: cat myfile it runs my open() function, which succeeds, then it runs my read() function, but the output of cat is nothing. It should output h but it doesn't. What am I doing wrong?
Also I find that under OSX, the exact same code only runs the open function, but never the read()
What could be the problem?
So my problem was that in the function: getattr(...) I did not specify the file size.
After doing: st->st_size = 4096; Everything was working fine :)

IOS text file is empty after apparently successful writing

IN IOS app, module written in C++ I am writing my data (map of basic strings and integers) to a text file. Using following method:
bool Recognizer::saveMap(const char * s)
{
if(trainingData.model && !trainingData.model.empty()) {
const string filename = string(s);
std::ofstream file(s, ios_base::trunc );
try{
if(! file.is_open())
{
file.open(s);
}
for (map<String,int>::iterator it=trainingData.idMap.begin(); it!=trainingData.idMap.end(); ++it)
{
cout << it->second << " " << it->first << endl;
file << it->first << endl << it->second << endl;
}
file.close();
}
catch(cv::Exception & e){
if(file.is_open())
file.close();
int code = e.code;
string message = e.err;
cerr << "cv::Exeption code: " << code << " " << message << endl;
return false;
}
std::streampos fileLength = iosFileSize(s);
cout << "Saved map to: " << filename << " length: " << fileLength << endl;
return true;
}
return false;
}
My contains one entry and console output indicates that two lines: string, string representing number have been written to my file.
Subsequent opening file for reading and reading using getline or using stream operator indicates that file is empty:
bool Recognizer::loadMap(const char * s)
{
std::streampos fileLenght = iosFileSize(s);
std::ifstream file(s, ios::in);
try{
if(file.is_open())
{
string name;
string lineName;
string lineTag;
int tag;
int count = 0;
while(getline(file,name))
{
if(getline(file,lineTag))
{
tag = stoi(lineTag,0,10);
count++;
cout << tag << " " << name << endl;
trainingData.idMap[name]=tag;
trainingData.namesMap[tag]=name;
}
}trainingData.personsCount=count;
file.close();
}
}
catch(cv::Exception & e){
if(file.is_open())
file.close();
int code = e.code;
string message = e.err;
cerr << "cv::Exeption code: " << code << " " << message << endl;
return false;
}
cout << "Loaded map from: " << s << " lenght: "<< fileLenght << endl;
return true;
}
I also copied from one of stackoverflow answers method returning file lenght and using it to verify lenghth of the file after write operation:
std::streampos iosFileSize( const char* filePath ){
std::streampos fsize = 0;
std::ifstream file( filePath, std::ios::binary );
fsize = file.tellg();
file.seekg( 0, std::ios::end );
fsize = file.tellg() - fsize;
file.close();
return fsize;
}
The file path passed to saveMap and loadMap seems to be legit. With path that the app could not write to, attempt to write caused exception.
There are no errors returned by write operation but both, attempts to read and iosFileSize() indicate that file is empty.
I am not sure if i need call file.open() and file.close() or file is open and closed automatically when output stream is created and later goes out of scope.
I experimented with those with the same result ( call to file.is_open returns true so the block calling file.open() is skipped.
What am I doing wrong?
I appreciate all responses.
It does not seem like you call file.flush(); anywhere in Recognizer::saveMap() after writing to the file stream. std::ofstream::flush() saves changes you've made to the file. Add file.flush(); between when you make changes to the code and when you close the file. See if that remedies your issue.
I also had the same issue. Using file.flush() everytime after you insert to a file can save your file.
However if you insert something like this, say,
file << "Insert This"; You will need to add file.flush().
But some people have issues, like if you just insert file << "Insert This" << endl; , this works fine. The key point here is that, std::endl calls flush() everytime it is used internally. you can say it is a shortend form of "\n" + flush().
I believe from looking at your code that you are overwriting your data when you open the file in the second program you should be using something like this.
std::fstream fs;
fs.open ("test.txt", ios::app)
instead of doing the ios::in

C++ getting a seg fault before even entering a function

I have a problem where I try to compress a file's data. Everything works up to the compression call, but it isn't the compression call itself, as the segfault is thrown before it. Showing my code will make it much clearer:
std::cout << "FILENAME: ";
std::cin >> filename;
if(!fileExists(filename))
{
std::cout << "ERR: FILE NOT FOUND." << std::endl;
continue;
}
std::cout << "Compressing file data...";
writeFile(filename, zlib_compress(readFile(filename)));
std::cout << " Done." << std::endl;
At the function zlib_compress...
std::string zlib_compress(const std::string& str)
{
std::cout << "DEBUG" << std::endl;
z_stream zs; // z_stream is zlib's control structure
memset(&zs, 0, sizeof(zs));
if (deflateInit(&zs, 9) != Z_OK)
std::cout << "deflateInit failed while compressing." << std::endl;
zs.next_in = (Bytef*)str.data();
zs.avail_in = str.size(); // set the z_stream's input
int ret;
char outbuffer[1073741824];
std::string outstring;
// retrieve the compressed bytes blockwise
do
{
zs.next_out = reinterpret_cast<Bytef*>(outbuffer);
zs.avail_out = sizeof(outbuffer);
ret = deflate(&zs, Z_FINISH);
if (outstring.size() < zs.total_out)
{
// append the block to the output string
outstring.append(outbuffer, zs.total_out - outstring.size());
}
} while(ret == Z_OK);
deflateEnd(&zs);
if(ret != Z_STREAM_END) // an error occurred that was not EOF
{
std::ostringstream oss;
oss << "Exception during zlib compression: (" << ret << ") " << zs.msg;
std::cout << oss.str();
}
return outstring;
}
I know, I know, that function needs work, I just C&P'd from somewhere to try it out.
But the thing is this:
std::cout << "DEBUG" << std::endl; is never called. The compiler says that the seg fault is coming from here:
std::string zlib_compress(const std::string& str)
> {
But why...? It was working earlier. I just don't know what went wrong!
Edit: Debugger output.
#0 00000000 0x00402cbb in __chkstk_ms() (??:??)
#1 004013BE zlib_compress(str=...) (C:\Users\***\Documents\Work\Programming\Compressor\z.cpp:5)
#2 00401DDA _fu15___ZSt4cout() (C:\Users\***\Documents\Work\Programming\Compressor\main.cpp:80)
char outbuffer[1073741824];
That's too large to put on the stack
You are taking a constant reference to a string as a parameter in your zlib_compress - you need to make sure that memory is available (whatever is returned from your readfile) in your zlib_compress. It would be good if you can share the prototype of your readFile function too.