0

For the purpose of education, I'm writing a small pair of functions which open a file as a binary file, read each character one at a time, change the value of said character and write to a new, encrypted file. (Note, this isn't true encryption per se.)

For some reason, I'm getting this error message in my debugger at the while-loop condition:

Thread 1: EXC_BAD_ACCESS (code=1, address=0x0)

I suspect the issue is with understanding pointer. Here is my program in it's entirety. Thanks ahead of time.

//  This program reads the contents of a file, encrypts it, and write the contents into a separate file.

#include <iostream>
#include <fstream>
#include <cctype>
#include <cstring>
#include <cmath>

using namespace std;

// Global Constants
const int POSITIVE_INT_LIMIT = 10;
const int NEGATIVE_INT_LIMIT = -10;
const int SLOPE_NEGATIVE = -1;
const int SLOPE_POSITIVE = 1;
const int STEP = 1;

// Function Prototypes
void encrypt(fstream *unEncryptedFile);
fstream *fileOpener();

int main() {

    encrypt(fileOpener());

    return 0;
}

/****************************************************
 *                  fileOpener()                    *
 *   Opens file with error checking and displays    *
 *   message if error, then exiting gracefully.     *
 ****************************************************/
fstream *fileOpener(){

    fstream inFile; // Create fstream object
    inFile.open("crypty.txt", ios::in | ios::binary); // Open file


    if (!inFile) {
        cout << "Error opening file." << endl;
        return NULL;

    } else {

        fstream *filePtr; // create a pointer to the file.

        filePtr = &inFile; // Pass the address of inFile to the pointer.

        return filePtr;
    }


}


/***************************************************
 *                    encrypt()                    *
 *    Encrypts a file with a simlpe algorithm.     *
 ***************************************************/ 
void encrypt(fstream &unEncryptedFile){

    char ch, cy;
    char *chPtr = &cy; // Initialize and assign char pointer.

    fstream cryptFile;
    cryptFile.open("decrypy.txt", ios::out | ios::binary);

    int amplitude = 0, slope = SLOPE_NEGATIVE; //Set initial amplitude and slope.

    int streamSize = 1;

/*      Encryption pattern inside while-loop.

 limit>     10                             *
            9                             * *
            8                            *   *
            7                           *     *
            6                          *       *
            5                         *         *
            4                        *           *
            3                       *             *
            2                      *               *
            1                     *                 *
 start>     0*2345678901234567890*2345678901234567890* -- < one hertz (cycle)
           -1 *                 *
           -2  *               *   (Number line: each integer represents a single while loop cycle.)
           -3   *             *
           -4    *           *
           -5     *         *
           -6      *       *
           -7       *     *
           -8        *   *
           -9         * *
 limit>    -10         *

 */
/*************************************************************
 The pattern above depictes a single character
 being read, and then the value of amplitude is added to it.

 *************************************************************/

    while (!unEncryptedFile.fail()) { // <--Code reports bug at this statement.

        ch = unEncryptedFile.get(); // Get the next character in the file.


        if (amplitude > NEGATIVE_INT_LIMIT && slope == SLOPE_NEGATIVE) {
            amplitude -= STEP;
            cy = ch + amplitude;
            cryptFile.write(chPtr, streamSize); //Adjusted character value, cy, is written to file.

        } else if (amplitude <= NEGATIVE_INT_LIMIT){
            slope = SLOPE_POSITIVE;
            amplitude = NEGATIVE_INT_LIMIT;
            cy = ch + amplitude;
            cryptFile.write(chPtr, streamSize); //Adjusted character value, cy, is written to file.


        } else if (amplitude < POSITIVE_INT_LIMIT && SLOPE_POSITIVE){
            amplitude += STEP;
            cy = ch + amplitude;
            cryptFile.write(chPtr, streamSize); //Adjusted character value, cy, is written to file.

        } else if (amplitude >= POSITIVE_INT_LIMIT){
            slope = SLOPE_NEGATIVE;
            amplitude = POSITIVE_INT_LIMIT;
            cy = ch + amplitude;
            cryptFile.write(chPtr, streamSize); //Adjusted character value, cy, is written to file.
        }

    }

//Files are closed.
unEncryptedFile.close();
cryptFile.close();

}
NonCreature0714
  • 5,744
  • 10
  • 30
  • 52
  • 1
    Do you know what happens to a function's local variables when that function returns? – user253751 Dec 02 '15 at 03:33
  • 2
    This is C++, so stop using raw pointers. Return a `std::unique_ptr` or something. – Ry- Dec 02 '15 at 03:34
  • @immibis, in C++, they still exist, right? – NonCreature0714 Dec 02 '15 at 03:38
  • @RyanO'Hara, can you amplify? – NonCreature0714 Dec 02 '15 at 03:38
  • @NonCreature0714 No, they get destroyed. (What would happen if they kept existing? Every program would have a huge memory leak, at least) – user253751 Dec 02 '15 at 03:45
  • @RyanO'Hara I agree, let's all shove as many concepts as possible at newbies to confuse them! – user253751 Dec 02 '15 at 03:57
  • @immibis, so I modified my code in this way: `int main(){` `fstream inFile;` `inFile.open("crypty.txt", ios::in | ios::binary);` `encrypt(inFile);` ... In order to not have locale variables from fileOpener() cause an issue in encrypt; instead, at the statement: `encrypt(inFile);` I get this error. "Call to implicitly-deleted copy constructor of 'fstream' (aka 'basic_fstream')" I suspect this is similar to, if not exactly the same issue, just in a different flavor, as you mentioned before. – NonCreature0714 Dec 02 '15 at 03:57
  • @immibis: It’s like a pointer except does what “newbies” expect. Don’t hold people back with memory management trivia. – Ry- Dec 02 '15 at 05:57

1 Answers1

0

I suspect the issue is with understanding pointer.

Probably, almost you right, but with understanding of pointers to local variables.

When you define local variables like this:

fstream inFile; // Create fstream object

inFile is allocated on the stack.

With following:

filePtr = &inFile

... you'll get pointer to some place on the stack in filePtr.

And when you exit that function:

return filePtr;

... stack portion, associated with function call will be returned to heap and filePtr will point to unused memory address, which will be overriden by next called function/executed code.

So, why not just return inFile itself?

ankhzet
  • 2,517
  • 1
  • 24
  • 31