Reputation:
I'm having trouble with this code. When I execute "PrepareEncryption" (in example), the code returns a valid pointer, but when I pass it on to "EncryptBig" it isn't valid no more (points to random numbers). My best bet is that the original struct is deleted. So how do I preserve it, if that's the problem? And I know that there is a memory leak btw.
struct filecrypt
{
FILE* bestand;
FILE* nieuwbstnd;
unsigned int positie;
unsigned int size;
unsigned int huidig;
float procentum;
};
struct filecrypt *PrepareEncryption(char* locatie)
{
struct stat file_status;
struct filecrypt origineel, *mirror;
int error;
char* nieuw;
if (stat(locatie, &file_status) != 0)
return NULL;
error = fopen_s(&origineel.bestand, locatie, "rb");
if (error != 0)
return NULL;
error = strlen(locatie)+5;
nieuw = (char*)malloc(error);
if (nieuw == NULL)
return NULL;
strcpy_s(nieuw, error-3, locatie);
strcat_s(nieuw, error, ".cpt");
error = fopen_s(&origineel.nieuwbstnd, nieuw, "wb+");
if (error != 0)
return NULL;
origineel.huidig = 0;
origineel.positie = 0;
origineel.procentum = 0.0f;
origineel.size = file_status.st_size;
mirror = &origineel;
return mirror;
}
float EncryptBig(struct filecrypt *handle)
{
int i, index = 0;
float calc;
char buf, *bytes = (char*)malloc(10485760); // 10 MB
if (bytes == NULL)
{
handle = NULL;
fcloseall();
return -1.0f;
}
for (i = handle->huidig; i < (handle->huidig+10485760); i++)
{
if (i > handle->size)
break;
fseek(handle->bestand, i, SEEK_SET);
fread_s(&buf, 1, 1, 1, handle->bestand);
__asm
{
mov eax, dword ptr [bytes]
add eax, dword ptr [index]
mov cl, byte ptr [buf]
xor cl, 18
xor cl, 75
not cl
mov byte ptr [eax], cl
mov eax, dword ptr [index]
add eax, 1
mov dword ptr [index], eax
}
}
fwrite(bytes, 1, i, handle->nieuwbstnd);
fseek(handle->nieuwbstnd, i, SEEK_SET);
handle->huidig += i;
calc = (float)handle->huidig;
calc /= (float)handle->size;
calc *= 100.0f;
if (calc == 100.0)
{
// GEHEUGEN LEK!
// MOET NOG BIJGEWERKT WORDEN!
fcloseall();
handle = NULL;
}
return calc;
}
void example(char* path)
{
float progress;
struct filecrypt* handle;
handle = PrepareEncryption(path);
do
{
progress = EncryptBig(handle);
printf_s("%f", progress);
}
while (handle != NULL);
}
Upvotes: 0
Views: 116
Reputation: 409196
It's because you return a pointer to a local variable.
Local variables are stored on the stack, and when a function returns that area of the stack is reused by other functions, and you are left with a pointer that now points to unused memory or memory now occupied by something else. This is undefined behaviour, and might sometimes work, might sometimes give you "garbage" data, and may sometimes crash.
Upvotes: 4
Reputation: 67715
You do:
mirror = &origineel;
return mirror;
origineel
is a local variable. The above is equivalent to:
return &origineel;
...you're returning a pointer to a local variable, that goes out of scope at the end of the function. The fact that it appears to sometimes return a valid pointer is just chance.
Use malloc
, or better yet, pass the pointer address to the target location as an argument to your function and don't return it:
int *PrepareEncryption(struct filecrypt *origineel, char* locatie);
struct filecrypt myStruct;
PrepareEncryption(&myStruct, "abc");
Upvotes: 0
Reputation: 26184
In PrepareEncryption you are returning pointer to struct filecrypt origineel
, which is allocated on stack (local object). This is the problem. Just after the function returns (ends its execution) the memory occupied by origineel
becomes invalid. You need to allocate it on the heap, by a call to malloc.
Upvotes: 0