4 Replies - 561 Views - Last Post: 16 November 2019 - 09:43 AM Rate Topic: -----

#1 Elfkam   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 01-November 19

Caesar cipher without key - need help with function free

Posted 16 November 2019 - 05:02 AM

Hello guys, everything working fine but when i start my program with valgrind i get 31 errors.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
void load(char* message){
	int position = 0;
	int letter;
	int i=0;
	while((letter = getchar()) != '\n' && letter != EOF){ // put letters into array message
		message = realloc(message, position+1 * sizeof(char));
		if (message == NULL){ // check memory
			free(message);
		}
		else{
			*(message +i) = letter; 
			i +=1;
		}
		position +=1;
		
	}
}
void cipher(char* message_1, char* message_2){
	int a=0; // value for finding key
	int b=0; // value for finding key
	int key=0;
	for (int i=0; i !=26; i++){ // shift 2 arrays
		a = 0;
		for (int j=0; message_1[j] != '\0'; j++){ // for all letters from message_1
			int x_1 = message_1[j] + i; 
			if (x_1 > 'z'){ 
					x_1 = x_1 - 26;
			}
			if (x_1 >= 'a' && x_1 <= 'z'){
				if (x_1 == message_2[j]){
					a +=1;
				}
			}
			if (x_1 > 'Z'){ 
				x_1 = x_1 - 26;
			}
			if (x_1 >= 'A' && x_1 <= 'Z'){			
				if (x_1 == message_2[j]){
					a +=1;
				}
			}
		}
		if (b < a){
			key = i;
			b = a;
		}
		
	}
	for (int i=0; message_1[i] != '\0'; i++){ // print deciphered message
		int x_2 = message_1[i];
		if (x_2 >= 'a' && x_2 <= 'z'){
			x_2 = x_2 + key;
			if (x_2 > 'z'){
				x_2 = x_2 - 26;
			}
		}
		if (x_2 >= 'A' && x_2 <= 'Z'){
			x_2 = x_2 + key;
			if (x_2 > 'Z'){
				x_2 = x_2 - 26;
			}
		}
	printf("%c", x_2);
	}
	printf("\n");
}
int main(){
	int error_1=2; //value for wrong input
	int error_2=0; //value for wrong input
	char* message_1;
	message_1 = ((char*)malloc(2 * sizeof(char)));
	char* message_2;
	message_2 = ((char*)malloc(2 * sizeof(char)));
	load(message_1);
	for (int i=0; message_1[i] != '\0'; i++){ // only for wrong inputs
		if (isalpha(message_1[i]) == 0){
			error_1 = 1;
		}
	}
	load(message_2);
	for (int i=0; message_2[i] != '\0'; i++){ // only for wrong inputs
		if (isalpha(message_2[i]) == 0){
			error_1 =1;
		}
	}
	int try_1 = 0; //value for wrong input
	int try_2 = 0; //value for wrong input
	for (int i=0; message_1[i] != '\0'; i++){ // only for wrong inputs
		try_1 +=1;
	}
	for (int i=0; message_2[i] != '\0'; i++){ // only for wrong inputs
		try_2 +=1;
	}
	if (try_1 != try_2){ // only for wrong inputs
		error_2 = 1;
	}
	if (error_1 == error_2){ // only for wrong inputs
		fprintf(stderr, "Error: Wrong input!\n");
		return 100;
	}
	if (error_1 == 1){ // only for wrong inputs
		fprintf(stderr, "Error: Wrong input!\n");
		return 100;
	}
	if (error_2 == 1){ // only for wrong inputs
		fprintf(stderr, "Error: Wrong lenght!\n");
		return 101;
	}
	cipher(message_1, message_2);
	free(message_1);
	free(message_2);	
}



Is This A Good Question/Topic? 0
  • +

Replies To: Caesar cipher without key - need help with function free

#2 jimblumberg   User is offline

  • member icon

Reputation: 5771
  • View blog
  • Posts: 17,672
  • Joined: 25-December 09

Re: Caesar cipher without key - need help with function free

Posted 16 November 2019 - 07:13 AM

What exactly are the errors?

It looks like you have quite a bit of memory leaking in your load function. Do you realize that the pointer being passed to that function is a copy? Meaning any changes made to where the pointer points (realloc()) inside that function is lost (memory leak) when the function returns.


Once you fix the above issue you may want to consider changing the malloc() in main() to allocate a reasonable sized array and only consider reallocing the memory when you exceed that size.


Jim
Was This Post Helpful? 2
  • +
  • -

#3 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7139
  • View blog
  • Posts: 24,248
  • Joined: 05-May 12

Re: Caesar cipher without key - need help with function free

Posted 16 November 2019 - 07:53 AM

Also recall that in C, there is no need to cast the return value of malloc().
Was This Post Helpful? 0
  • +
  • -

#4 Elfkam   User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 5
  • Joined: 01-November 19

Re: Caesar cipher without key - need help with function free

Posted 16 November 2019 - 08:00 AM

Its my first work with dynamic array and with valgrind. So i am confused what its mean.
==6472== Memcheck, a memory error detector
==6472== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==6472== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==6472== Command: ./english
==6472== 
a
==6472== Invalid read of size 1
==6472==    at 0x108AEF: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d040 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108A9C: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A7E: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
a
==6472== Invalid read of size 1
==6472==    at 0x108B54: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d090 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108B01: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A8C: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
==6472== Invalid read of size 1
==6472==    at 0x108B87: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d040 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108A9C: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A7E: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
==6472== Invalid read of size 1
==6472==    at 0x108BAC: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d090 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108B01: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A8C: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
==6472== Invalid read of size 1
==6472==    at 0x1089AC: cipher (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108C60: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d040 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108A9C: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A7E: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
==6472== Invalid read of size 1
==6472==    at 0x108A4B: cipher (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108C60: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d040 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108A9C: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A7E: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 

==6472== Invalid free() / delete / delete[] / realloc()
==6472==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108C6C: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d040 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108A9C: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A7E: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
==6472== Invalid free() / delete / delete[] / realloc()
==6472==    at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108C78: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Address 0x522d090 is 0 bytes inside a block of size 2 free'd
==6472==    at 0x4C31D2F: realloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x10888D: load (in /home/jan/Documents/PRP/HW05/english)
==6472==    by 0x108B01: main (in /home/jan/Documents/PRP/HW05/english)
==6472==  Block was alloc'd at
==6472==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6472==    by 0x108A8C: main (in /home/jan/Documents/PRP/HW05/english)
==6472== 
==6472== 
==6472== HEAP SUMMARY:
==6472==     in use at exit: 2 bytes in 2 blocks
==6472==   total heap usage: 6 allocs, 6 frees, 2,054 bytes allocated
==6472== 
==6472== LEAK SUMMARY:
==6472==    definitely lost: 2 bytes in 2 blocks
==6472==    indirectly lost: 0 bytes in 0 blocks
==6472==      possibly lost: 0 bytes in 0 blocks
==6472==    still reachable: 0 bytes in 0 blocks
==6472==         suppressed: 0 bytes in 0 blocks
==6472== Rerun with --leak-check=full to see details of leaked memory
==6472== 
==6472== For counts of detected and suppressed errors, rerun with: -v
==6472== ERROR SUMMARY: 33 errors from 8 contexts (suppressed: 0 from 0)



Was This Post Helpful? 0
  • +
  • -

#5 Skydiver   User is offline

  • Code herder
  • member icon

Reputation: 7139
  • View blog
  • Posts: 24,248
  • Joined: 05-May 12

Re: Caesar cipher without key - need help with function free

Posted 16 November 2019 - 09:43 AM

Re-read jimblumberg's post #2. What valgrind is telling you is the same thing that Jim is telling you.

Consider this:
On line 74, you allocated 2 bytes and stored a pointer to that block of memory in message_1.
You pass a copy of that pointer to load() on line 77 and it stored into the variable message in load().
When the user entered a letter in to feed getchar() in load(), you free that block of 2 bytes and allocate a new block of 1 byte* on line 9 when you called realloc. There is no guarantee that realloc() will just re-use the same block of memory and just make it bigger. (realloc() is allowed to just resize an existing block of memory, or allocate a new block elsewhere. This is an implementation detail that is opaque to you.) You stored a pointer to that new block in message (Depending on how much input you give load(), more reallocations happen.)
After you exit load() control comes back to main().
The local variable message_1 is still pointing to the memory location originally allocated on line 74. But that block was freed by line 9. So when you access the memory with message_1[i] on line 78 you are accessing memory that may not belong to you and thereby invoking undefined behavior. It all really depends on whether realloc() just resized the existing block, or if it allocated a new block.

* There is another bug in the way you compute the size of the new block as well as prepare the string to be filled out. Recall that multiplication has a higher precedence than addition. So position+1 * sizeof(char) is actually computed as position + (1 * sizeof(char)). I believe that your intent was to keep allocating space for a null terminator, so you really wanted to compute (position + 1) * sizeof(char). But even if you put the parethenses, this is still a failure because position starts of at zero, so you end up allocating space for just one character and have no space for the null terminator. And in the end, load() never places a null terminator into the string.
Was This Post Helpful? 3
  • +
  • -

Page 1 of 1