Heavy use of pointers - Segmentation Faults

closed account (zvRX92yv)
So I was making an encrypted diary program for fun.. And I have been getting segmentation faults.. I can't figure out where the problem is coming from..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#include <iostream>
#include <fstream>
#include <time.h>

// Definitions
typedef unsigned char byte;        // For small numbers.
#define XOR  // Use XOR encryption

// Utilities - Added this here because switchCrytion's prototype uses getStringLength.
fpos_t fileSize(std::fstream *file);  // Get the file size.
byte getStringLength(char *string);   // Get string length.

// Data Pre-Processing
char* switchCryption(char *data, char *key, fpos_t dataLength, byte keyLength, bool encrypting = false);
fpos_t* getEntryPos(char *content, fpos_t size);  // Gets all the positions of the Entries.

// Data Processing
char* getDiaryName(char *content);  // Get the name of the diary.

int main()
{
    std::fstream diary;       // The variable for the diary
    fpos_t *entryPos, size;   // Storage of the positions of the entries in a diary
    char path[260], key[64];  // MAX_PATH == 260; The key == (de)cipher
    char *content;            // Storage of the whole file

    // Get Directory
    std::cout << "Enter the directory of the DIARY."
              << "\nIf the file/directory does not exist, it will be created for you."
              << "\nIf the file is in the same directory as the program, just enter the file name."
              << "\nThe extension prefix will be added automatically. ( .dry )"
              << "\n\n  - ";
    getDir:
    std::cin.getline(path, 260);

    diary.open(path, std::fstream::in | std::fstream::out | std::fstream::binary | std::fstream::app);

    if ( diary.bad() )
    {
        std::cout << "\n\nERROR - Could not access/create the file at said directory!"
                  << "\nTry again!"
                  << "\n - ";
        goto getDir;
    }

    // Initialize size; Get everything all content from the diary
    size = fileSize(&diary);
    content = new char [size];
    diary.read(content, size);

    // Get the key
    std::cout << "\nFile access/creation successful."
              << "\nWe need the key to decrypt the entries."
              << "\n\nEnter it below, it will also be used to encrypt new entries."
              << "\n\n  - ";
    std::cin.getline(key, 64);
    delete [63 - getStringLength(key)] key;

    // Decrypt; Get all entry positions

    /* RUNTIME ERROR START */
    content = switchCryption(content, key, size, getStringLength(key));
    std::cout << content; // DEBUG
    entryPos = getEntryPos(content, size);
    /*  RUNTIME ERROR END  */

    // User interaction.
    std::cout << "\n\nDiary Name - " << getDiaryName(content)
              << "\nTotal Entries - " << entryPos[0]
              << "\n\n1 - Read Diary"
              << "\n2 - Write to the Diary";

    std::cout << content;
    std::cin.ignore();

    return 0;
}

char* switchCryption(char *data, char *key, fpos_t dataLength, byte keyLength, bool encrypting)
{                                                                                     // Decryption / Encrytion
    char *processed = new char [dataLength];                                          // data =

    // Remove the null terminator from the key.
    delete key;

#ifdef XOR    // Use XOR encryption

    byte slot = 0, keySlot = 0;

    while ( slot < dataLength )
    {
        if ( keySlot >= keyLength )
            keySlot = 0;

        processed[slot] = data[slot] ^ key[keySlot];
        slot++;
        keySlot++;
    }

#elif defined AES  // Use AES-256 encryption

    /* TODO - Code *this; */

#else
    #warning switchCryption() - cryption type not specified
#endif

    return processed;
}

fpos_t* getEntryPos(char *content, fpos_t size)  // Finds the positions of all entries;
{                                                // content = content, size = byteSize.
    fpos_t *entryPos = new fpos_t [128], arrayLimit = 127, slot = 0;

    entryPos[0] = 0;

    while ( slot < size )
    {
        if ( slot == 0 )
            { slot = content[slot] + 1; continue; }

        if ( slot >= arrayLimit )
            { entryPos = new fpos_t [64]; arrayLimit += 64; }

        content[0]++;
        slot += content[slot] + 1;
    }

    return entryPos;
}

char* getDiaryName(char *content) // Extract the diary name, the length is the first byte.
{
    char *name = new char [(unsigned int) content[0]];
    fpos_t length = content[0], slot = 1;
    while (slot < length)
    {
        name[slot] = content[slot+1];
        slot++;
    }
    return name;
}

fpos_t fileSize(std::fstream *file) // Get the File Size
{
    fpos_t size, lastPos = file->tellg();
    file->seekg(0, std::fstream::end);
    size = file->tellg();
    file->seekg(lastPos);
    return size;
}

byte getStringLength(char *string)
{
    byte length = 0;
    while ( string[length] != '\0' )
        length++;
    return length;
}


Here is what it does -
- Get the directory of the diary and open it
- Get the decryption/encryption key and decrypt everything
- Get the diary title
- Prompt for options
- To-do : Reading entries and writing to them, creation.

In the diary, it's stored like -
[1B - Length of title][?B - Title text without \0][1B - Length of entry][?B - Entry] ...
But everything is encrypted.

Please, excuse me because it isn't compiling right now.
Maybe if you could help me with that too.. xD
Last edited on
From a quick view: Line 57 is completely nonsense. what do you think delete[] does? Discard that line. You cannot delete on objects when you didn't call new before. The same applies to line 84.

Looks like you misunderstood the point of dynamic memory?

Why don't you use std::string? That'd make things much easier.

closed account (zvRX92yv)
@coder777 -

I didn't use std::string because I need to work with it char by char, as you could've seen in switchCryption(). And I forgot that it was a normal array, not a pointer, sorry. I was just trying to get rid of the extra bytes.
Using std::string, you can still access on a single char basis, using the index notation as you would with an array.
Topic archived. No new replies allowed.