I'm working with a simple program to test Crypto++ and so I can get used to using the library. It's not Crypto++ that is causing the errors, though.
I'll include the code at the end, but the simple run-down is this:
I load in data from a file, 1,669,823 bytes of data. I compress it using the Gzip class in Crypto++. I check the compressed length, which comes out to be 1,663,424 bytes. (I didn't expect a lot of compression in this file. It's just one of several files I'm testing.)
After compression, I query the object I've made from the Gzip class for the length of the compressed data. Then I use this line:
Code:
char* zipData[zipLen];
This works with smaller files, but not with the bigger file I'm using.
I figure, at this point, the total memory I'm using could be approximately 3 MB. (Rounding off, 1 MB for the original data, 1 MB for the compressed data in my Gzip object, and 1 MB that I'm allocating when I get "Segmentation Fault 11" as an error.
I'm new to C++ and haven't had to worry about memory issues since the 1980s, when I was using 6502 Assembler on an Apple //e (with a 64k address space). I've been using Perl and Java in the past 10 years, but now that I have to think about memory, even on today's systems, 3 MB sounds like a lot to me - but I don't see how this can be so much that it should crash - unless there's some rules I don't know.
This works with a file 521k in length. I may not be freeing up memory (feel free to point that out), but this happens if the 1MB file is the first file I test, even before I'd be destroying or deleting anything.
(There is some extra code in the main() routine, but that's just adding arguments to a linked list for some other testing I will be doing.)
Here's the code:
Code:
#include <iostream>
#include <list>
#include <sstream>
#include <utility>
#include <string>
#include "poppler/cpp/poppler-document.h"
#include "../Crypto++/blowfish.h"
#include "../Crypto++/cryptlib.h"
#include "../Crypto++/files.h"
#include "../Crypto++/hex.h"
#include "../Crypto++/modes.h"
#include "../Crypto++/gzip.h"
using namespace std;
void testZip(string fileName) {
using namespace CryptoPP;
cout << "Experimenting file: " << fileName << endl;
unsigned long sourceLen;
//Load the file into a char*
ifstream inStream((char*) fileName.c_str(), ios::in | ios::binary);
inStream.seekg(0, inStream.end);
sourceLen = inStream.tellg();
inStream.seekg(0, inStream.beg);
char* inData = new char[sourceLen];
inStream.read(inData, sourceLen);
inStream.close();
cout << " Original length: " << sourceLen << endl;
//Zip file
Gzip inZip;
inZip.SetDeflateLevel(Gzip::MAX_DEFLATE_LEVEL);
inZip.Put((const byte*) inData, sourceLen);
inZip.MessageEnd();
unsigned long zipLen = inZip.MaxRetrievable();
cout << " Compressed length: " << zipLen << endl;
//This next line is the one that crashes the program with a 1 MB file
char* zipData[zipLen];
inZip.Get((byte*) zipData, zipLen);
//Unzip file
Gunzip outZip;
outZip.Put((byte*) zipData, zipLen);
outZip.MessageEnd();
unsigned long outLen = outZip.MaxRetrievable();
cout << " Output length: " << outLen << endl;
char* outData[outLen];
outZip.Get((byte*) outData, outLen);
if (sourceLen == outLen) {
cout << " Input and output DO match in length." << endl;
int iTest = memcmp((const byte*) inData, (const byte*) outData, sourceLen);
cout << " Memory comparison result: " << iTest << endl;
} else {
cout << " Input and output do NOT match in length." << endl;
}
return;
}
int main(int argc, char* argv[]) {
list<string> inFiles;
int i;
cout << "Command given: " << argv[0] << endl << endl;
for (i = 1; i < argc; i++) {
cout << "Adding argument " << i << ": " << argv[i] << endl;
inFiles.push_back(argv[i]);
}
cout << "-----------------------------" << endl << endl;
testZip(argv[1]);
cout << "-----------------------------" << endl << endl;
cout << endl;
return 0;
}