Error message is: The instruction at “0x7c810eac” referenced memory at “0x00000000”. The memory could not be “written”.
If I remove the destructor everything is fine. But I do not understand what is happening here. Everywhere I read that I should close handles, but here code won’t let me. (Yes I know that I can do it manually… but that is a unnecessary line in client code that I think should be handled by object.)
#include <windows.h>
#include <iostream>
#include <string>
struct fileHandle {
HANDLE hFile;
fileHandle(std::string path) {
hFile = CreateFile(path.c_str(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, FILE_ATTRIBUTE_ARCHIVE, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
printf("error: INVALID_HANDLE_VALUE");
}
}
~fileHandle() {
CloseHandle(hFile);
}
void save(std::string data) {
if (!WriteFile(hFile, data.c_str(), data.size(), NULL, NULL)) {
printf("WriteFile failed: ", GetLastError());
}
}
};
int main() {
fileHandle my_handle("test_file.txt");
my_handle.save("some text");
}
Update: this happens when file doesn’t exist. When file do exist program print errors, but this is intended. I’m here asking co cover only this case when file is created (I know how to rewrite handle creating to cover existing file.)
Update 2: I didn’t mention that this code works and writes to file. Memory error is triggered at the very end.
Please compile all your code with -Wall. Saves a whole lot amount of time.
In your code
printfwhich has an invalid format string. Correct solution forprintfwould be (notice the %lu):If you would have compiled with
-Wall, your code would have given the warning:Also you should print errors to
stderras it is unbuffered.printfuses buffers and that’s why you did not get any output. Also a good idea to add a\nafter the errors.Also read the other answers to improve your code. Use the rule of three.
After reading the comment I realized that this is not the segfault reason indeed. (Also look at Ron Burk’s solution to see what went wrong.)
According to the Windows API documentation,
lpNumberOfBytesWrittenparameter can beNULLonly when thelpOverlapped parameteris notNULL.So you have to give a pointer to a DWORD where WriteFile can store how many bytes it actually read. The final save would be:
If the file exists, the error does not pop up, because passing INVALID_HANDLE_VALUE to WriteFile seems to make WriteFile return earlier than it uses your pointer.