C programming 2d dynamic string array

Hello and happy new year everyone !
I have to do this project for Christmas and my time is running out...
The project is to make an English to Greek dictionary and in order to do that i need a 2D dynamic array.
This is what i've come up with:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#define s_size 256
void show_menu();
unsigned int Add_El( char**, char**,unsigned int);
void save_file( char**, char**,unsigned int);
int main()
    unsigned int Sum_of_Terms=0;
    char **En=NULL,**Gr=NULL;
    char ch,save;
   // Memory Initialization.
   En = ( char**)malloc(sizeof( char* ));
   Gr = ( char**)malloc(sizeof( char* ));
    printf("\nInsert option: ");
    ch = getch();

            printf("Would you like to save changes?(y/n): ");
            save = getch();

        }while(save!='y' && save!='n');


    if(ch>'6' || ch<'1') printf("Invalid choice!\n");
        case '1':Sum_of_Terms = Add_El(En,Gr,Sum_of_Terms);
    printf("\n Sum: %d",Sum_of_Terms);


return 0;
void show_menu()
    printf("\n***************** MENU *********************\n");
    printf("1. Insert new word. \n");
printf("2. Modify an existing entry. \n");
printf("3. Delete an entry. \n");
printf("4. Translate a word. \n");
printf("5. Translate a sentence. \n");
printf("6. EXIT.\n");
unsigned int Add_El(char **En,char **Gr,unsigned int w_count) // w_count = word count.
    int i;
    char s[s_size];
    En = (char**)realloc(En,sizeof(char* )*(w_count));
Gr = (char**)realloc(Gr,sizeof(char* )*(w_count));

if(En==NULL || Gr==NULL)
    printf("Could Not Allocate Memory (1).\n");

        //English Word.
            printf("Could not allocate memory (2).\n");
            printf("Insert English Word: ");

        //Greek Word.
            printf("Could not allocate memory (2).\n");
            printf("Insert Greek Word: ");
            Gr[w_count-1]=(char*)malloc((strlen(s)+1)*sizeof( char));
            Gr[w_count-1] = strdup(s);


    //Test_point 1.
        printf("\n %s =  %s \n",En[i],Gr[i]);

}//else (1)

return w_count;

The problem I have is that while for the first 2 entries it works fine, at the third entry (w_count=3) it fails to allocate memory.
I've been trying to figure it out for quite a while but I haven't come up with anything yet and it's getting really annoying.
I 'd really appreciate some help. Thanks in advance!

I couldn't run this (i dont have conio.h) but I'm not sure why you keep casting the returns from malloc, as char* and char**.

I had a look but also don't have conio. Reading it is a bit difficult without cleaning up the code.

Anyway, this is your bug:

Your Add_El function is receiving a copy of your En pointer, not a reference to it, so it won't change the pointer En in main function when you realloc in Add_el. Check if I am correct:

Print your pointers (printf("%p", En)) before and after realloc to check if En pointer has changed or not inside Add_El, then print your pointers also in main before and after calling Add_El to see if the pointer En has changed in main. Your program will break as soon as En in main starts to mismatch En in Add_El. These are two different copies of the pointer.

You have the same problem with Gr - pointer in main and Gr pointer in Add_El - they are not same pointer, but two copies.

To help yourself develop this code further, I suggest you could simplify memory handling and improve readability by declaring a struct and reallocing an array of that struct:

struct X {
    char * En;
    char * Gr;

Then malloc and realloc array using sizeof(struct X) similar to this:

realloc(DictionaryArray,sizeof( struct X )*(w_count));

Keeping things together could help you finding memory-related bugs.

Also, consider putting the whole dictionary in one struct, and then passing a pointer to a copy of that struct to your Add_El function, to make sure you always have all your pointers in one place. Something like this:

struct Y {
    struct X * arrayOfWordPairs;
    unsigned int w_count;

The call to Add_El could then be simplified like this:

unsigned int Add_El(struct Y * dictionary);

And you can dereference w_count like this:



dictionary->arrayOfWordPairs[w_count - 1].En = strdup(ENGLISH_WORD);
dictionary->arrayOfWordPairs[w_count - 1].Gr = strdup(GREEK_WORD);

I can also see that this code will leak memory allocated in malloc, because the pointer is overwritten by strdup without being released:


I hope I am not going over your head (since your code is telling me that you are either a C beginner, or very stressed up).