free() caused segmentation fault - c

In this program, there is a segmentation fault. The program can print out "loop end" successfully and segmentation fault appeared after "loop end", which means there is not error in read_name function. But I could not figure out any error in my free_memory function. Could anyone help me figure out? Thank you.
input file:
9
Clinton, Hillary R.
Bonds, Bobby S.
Bonds, Barry L.
Clinton, William I.
Clinton, Chelsea T.
Bush, Laura M.
Bush, George W.
Bush, Jenna F.
Bush, Barbara G.
program:
#include <stdio.h>
#include <malloc.h>
#include<string.h>
void alloc(char ***surname, char ***first, char **mid_init, int num);
void read_names(FILE *inp, char **surname, char **first, char *mid_init, int num );
void free_memory(char **surname, char **first, char *mid_init, int num);
int main(int argc, char *argv[])
{
int num = 0;
char **surname, **first, *mid_init;
FILE *inp = fopen(argv[1], "r");
FILE *outp = fopen(argv[2], "w");
char array[79];
fscanf(inp, "%d", &num);
printf("%d\n", num);
fgets(array, 79, inp);
alloc(&surname, &first, &mid_init, num);
read_names(inp, surname, first, mid_init, num);
free_memory(surname, first, mid_init, num);
fclose(inp);
fclose(outp);
return 0;
}
void alloc(char ***surname, char ***first, char **mid_init, int num)
{
int i;
*surname = (char**)malloc(num * sizeof(char*));
*first = (char**)malloc(num * sizeof(char*));
*mid_init = (char*)malloc(num * sizeof(char));
for(i=0; i<num; i++)
{
(*surname)[i] = (char*)malloc(15*sizeof(char));
(*first)[i] = (char*)malloc(10*sizeof(char));
}
}
void read_names(FILE *inp, char **surname, char **first, char *mid_init, int num )
{
char *token, array[79];
char delim[6] = ", .\n";
int i=0;
fgets(array, 79, inp);
printf("loop begins\n");
for(i=0; i<num; i++)
{
fgets(array, 79, inp);
printf("%s", array);
token = strtok(array, delim);
strcpy( (surname[i]), token);
printf("%s ", (surname[i]));
token = strtok(NULL, delim);
strcpy( (first[i]), token);
printf("%s ", (first[i]));
token = strtok(NULL, delim);
*mid_init = token[0];
printf("%s\n", mid_init);
printf("\n\n");
}
printf("\nloop ends\n");
}
void free_memory(char **surname, char **first, char *mid_init, int num)
{
int i;
for(i=0;i<num;i++)
{
free((surname)[i]);
free((first)[i]);
}
free(surname);
free(first);
free((mid_init));
}

First off, you're limiting yourself to 14-character first names and 9-character last names, so that would be the first thing I'd check, that your names aren't longer than this.
If they are, you'll probably corrupt the memory arena when copying them.
One way to check this is to simply print the length of token every time you set it, such as:
token = strtok(array, delim);
printf ("DEBUG: token length is %d\n", strlen (token));
Keep in mind that corruption does not necessarily have a visible immediately or even ever. In this case, what's most likely happened is that you've overwritten a vital piece of inline control information in the memory arena, such as a memory block size or a pointer to another memory block.
However, there's no code actively checking for that when you write to memory so it's probably only found when you next try to do a memory allocation or de-allocation call.
Your next call like this after the corruption is your free calls and that's almost certainly where it's being found, because the arena is corrupt.
Bottom line, writing beyond the end of allocated memory is undefined behaviour. That means you shouldn't do it.
If it turns out your names aren't too long (as you state in a comment), you need to then ask yourself why you have a superfluous fgets(array, 79, inp); in your code. I understand why it's needed in main so as to move to the next line after inputting the line count with a call to fscanf. And that one does its job well.
However, you have another one at the start of read_names which effectively throws away the first name in your list. That's going to cause problems because, while your code thinks there are X names in the file, you've thrown away the first one meaning that there are only X - 1 remaining. You can tell this because, when you begin to print out the names, the first one from the file appears to be missing.
If you remove the fgets at the start of read_names, you should find it's okay.
As an aside, there's a couple of other changes I'd make to the code. First you really should check all those malloc calls in case one of them fails. That's the general rule for all functions that can fail when you rely later on them not having failed.
Second, I'm not really a big fan of ever multiplying by sizeof(char) - this is guaranteed by the standard to always be 1, so multiplying by it clogs up the code and makes it less readable.

Try replacing
token = strtok(NULL, delim);
*mid_init = token[0];
printf("%s\n", mid_init);
with
token = strtok(NULL, delim);
mid_init[i] = token[0];
printf("%c\n", mid_init[i]);
When mid_init memory chunk is filled with garbages without any null in it, 'printf("%s\n", mid_init);' might read beyond the data segment causing segmentation fault.
But #paxdiablo's answer has a much better chance to be the case here.
#Bruce, segmentation fault doesn't always appear at the exact spot it happened.

I don't know why you are getting a segmentation fault, but if I was writing this, I would try and make it a bit simpler (I don't think you are doing yourself any favors) - it makes no sense to pass around something like char ***surname.
This is only my personal opinion, but I would do something like this:
#include <stdio.h>
#include <malloc.h>
typedef struct {
char **data;
unsigned int count;
unsigned int actualSize;
} StringArray;
void StringArray_init(StringArray *array)
{
array->count = 0;
array->actualSize = 0;
}
void StringArray_add(StringArray *array, char* value)
{
if (array->actualSize == 0)
{
array->data = (char**)malloc(sizeof(char*)* 4);
array->actualSize = 4;
}
else
{
if (array->count >= array->actualSize)
{
array->actualSize *= 2;
array->data = (char**)realloc(array->data,sizeof(char*) * array->actualSize);
}
}
array->data[array->count] = value;
array->count++;
}
char* StringArray_get(StringArray *array, unsigned int position)
{
if (position < array->count)
return array->data[position];
else
return 0;
}
void StringArray_clear(StringArray *array)
{
if (array->count >0) free(array->data);
array->count = 0;
array->actualSize = 0;
}
int main ()
{
StringArray surname;
StringArray_init(&surname);
StringArray_add(&surname, "Smith");
StringArray_add(&surname, "Jones");
for(int i=0;i<surname.count;i++)
{
printf("%s\n", StringArray_get(&surname,i));
}
StringArray_clear(&surname);
}
What the above code is doing is allocating memory when you add a value, but instead of allocating space for one item, it adds enough for four. If you get to the point where you add a fifth, it will then double the space to 8 items. This method should help with memory fragmentation. I'm also using a structure, which just makes it a bit easier to pass this array around.
I could also do something like this if I wanted to allocate memory for the strings (just include the string.h header):
int main ()
{
StringArray surname;
StringArray_init(&surname);
char *name = (char*)malloc(sizeof(char) * 6);
strcpy(name,"Smith");
StringArray_add(&surname, name);
name = (char*)malloc(sizeof(char) * 6);
strcpy(name,"Jones");
StringArray_add(&surname, name);
for(int i=0;i<surname.count;i++)
{
printf("%s\n", StringArray_get(&surname,i));
}
// Free memory
for(int i=0;i<surname.count;i++)
{
char *name = StringArray_get(&surname,i);
if (name != NULL) free(name);
}
StringArray_clear(&surname);
}
The size of each name is 6 because there are 5 characters and an extra one for 0, which is the string terminator.
Sorry if this doesn't directly answer your question, but hope it helps.

Bruce,
In your data file, you need a blank line between the number and list of names because of the first fgets() at the beginning of read_names() consumes the second line.
Because the program skipped the second line, it could read only 8 names and the last line read was a blank line, which caused strtok to return a null and the next strcpy tried to read from address 0, which is, of course, a segmentation fault.
And in my machine, the fault happened before printing "loop ends".
You need to check the return values of function calls (strtok in this case) for possible errors. Otherwise you will be wasting a lot of time debugging like this.

Related

How can I implement a function to concatenate to a char* and not char array?

How can I implement a function that will concatenate something to a char* (not char array)?
Example of what I want:
#include <stdio.h>
#include <string.h>
int main() {
char* current_line;
char temp[1];
sprintf(temp, "%c", 'A');
// This causes a seg fault. I of course don't want that, so how do I get this to work properly?
strcat(current_line, temp);
return 0;
}
How can I fix this to work properly (and please, tell me if I need to add anything to my question or point me in the right direction because I couldn't find anything)?
Edit: I made this but it seg faults
char* charpointercat(char* mystr, char* toconcat) {
char ret[strlen(mystr) + 1];
for(int i = 0; mystr[i] != '\0'; i++) {
ret[i] = mystr[i];
}
return ret;
}
You have 3 problems:
You do not allocate memory for current_line at all!
You do not allocate enough memory for temp.
You return a pointer to a local variable from charpointercat.
The first one should be obvious, and was explained in comments:
char *current_line only holds a pointer to some bytes, but you need to allocate actual bytes if you want to store something with a function like stracat.
For the secoond one, note that sprintf(temp, "%c", 'A'); needs at least char temp[2] as it will use one byte for the "A", and one byte for terminating null character.
Since sprintf does not know how big temp is, it writes beyond it and that is how you get the segfault.
As for your charpointercat once the function exits, ret no longer exists.
To be more precise:
An array in C is represented by a pointer (a memory address) of its first item (cell).
So, the line return ret; does not return a copy of all the bytes in ret but only a pointer to the first byte.
But that memory address is only valid inside charpointercat function.
Once you try to use it outside, it is "undefined behavior", so anything can happen, including segfault.
There are two ways to fix this:
Learn how to use malloc and allocate memory on the heap.
Pass in a third array to the function so it can store the result there (same way you do with sprintf).
From the first code you posted it seems like you want to concatenate a char to the end of a string... This code will return a new string that consists of the first one followed by the second, it wont change the parameter.
char* charpointercat(char* mystr, char toconcat) {
char *ret = (char*) malloc(sizeof(char)*(strlen(mystr) + 2));
int i;
for(i = 0; mystr[i] != '\0'; i++) {
ret[i] = mystr[i];
}
ret[i] = toconcat;
ret[i + 1] = '\0';
return ret;
}
This should work:
char* charpointercat(char* mystr, char* toconcat) {
size_t l1,l2;
//Get lengths of strings
l1=strlen(mystr);
l2=strlen(toconcat);
//Allocate enough memory for both
char * ret=malloc(l1+l2+1);
strcpy(ret,mystr);
strcat(ret,toconcat);
//Add null terminator
ret[l1+l2]='\0';
return ret;
}
int main(){
char * p=charpointercat("Hello","World");
printf("%s",p);
//Free the memory
free(p);
}

Copy a string on a structure element in C

I don't understand why my string is not copied.
The strings structures are similar to this one "KS 2H 5C JD TD"
Here is my code (the comments are all that I tried (memcpy and strcpy)):
typedef struct Hand Hand;
struct Hand {
char *cards;
double power;
};
Hand* initHand(char *set){
Hand *hand = malloc(sizeof(*hand));
if(hand == NULL)
exit(EXIT_FAILURE);
char card[5][3];
//strcpy(hand->cards,*cards);
int i=0;
char *p = strtok (set, " ");
while (p != NULL)
{
card[i] = p;
printf("%s\n",p);
p = strtok (NULL, " ");
i++;
}
hand->power=0;
}
I was willing to copy every 2 letters in an array with strtok (this is what I wanna do); then I tried to copy the whole string.
Thanks a lot. I understood my mistakes:
Mistakes:
I didn't know that strtok is a destructive function (I was trying to edit a readonly data since I was using a constant).
I didn't allocate memory for char *cards
Solution:
make a copy of the set.
allocate memory.
Here's the code that worked for me:
struct Hand {
char cards[5][3];
double power;
};
Hand* initHand(char *set){
Hand *hand = malloc(sizeof(*hand));
if(hand == NULL)
exit(EXIT_FAILURE);
char copy_set[15]="";
strcpy(copy_set,set);
char **str = (char**) malloc(5*sizeof(char*));
for(int i=0; i<3; i++){
str[i]= (char) malloc(3*sizeof(char));
}
strcpy(hand->cards,str);
int i=0;
char *p = strtok (copy_set, " ");
while (p != NULL)
{
strcpy(hand->cards[i], p);
p = strtok (NULL, " ");
i++;
}
hand->power=0;
return hand;
}
I think that this is reasonably correct code — a relatively simple modification of the code shown in revision 2 of the answer by the OP. There's always room for improvement, of course.
#include <stdlib.h>
#include <string.h>
struct Hand
{
char cards[5][3];
double power;
};
typedef struct Hand Hand;
extern Hand *initHand(const char *set);
Hand *initHand(const char *set)
{
Hand *hand = malloc(sizeof(*hand));
if (hand == NULL)
exit(EXIT_FAILURE);
char copy_set[15] = "";
strcpy(copy_set, set);
int i = 0;
char *p = strtok(copy_set, " ");
while (p != NULL)
{
strcpy(hand->cards[i++], p);
p = strtok(NULL, " ");
}
hand->power = 0;
return hand;
}
#include <stdio.h>
int main(void)
{
Hand *hand = initHand("KS 2H 5C JD TD");
for (int i = 0; i < 5; i++)
printf("Card %d: [%s]\n", i, hand->cards[i]);
printf("Power: %.2f\n", hand->power);
free(hand);
}
As I noted in a comment, the variable str isn't needed. With the revised structure, there is no need to allocate extra cards. I've marked the string input as const. Arguably, it would be better to do a dynamic memory allocation for copy_set (remembering to release the copy too), or at least check that the given data will fit in the allocated space. It would probably be better to print an error message before unilaterally exiting on a memory allocation failure. It is good to check for the failure. It is not good to exit with saying why. It would probably be better to return NULL on failure, and then let the calling code detect and handle the problem.
There's a simple test program attached to the code too.
Be cautious about using strtok(); it is dangerous to use it in library functions. You should generally use strtok_r() (POSIX) or strtok_s() (Microsoft) for preference.

Int to char array as a function returning an array of char the simple way

I have been looking on internet for this and so far i just found a lot of questions for specific answer and not a general one.
i am kind of rusty on C. And i want to make a function that will return an array of char.
this is what i got and is not working. basically a way to convert a byte array to an array of chars to do atoi later..
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char *get_char(int my_byte[], int packetsize)
{
char *array_char=(char *) malloc(sizeof(char)*10); //trying this but didnt work
// char array_char[10]; //i had it like this before(was told to do it)
for(int i=0;i<10;i++)
{
array_char[i]=my_byte[i]+0;
}
return array_char;
}
int main()
{
int byte_array[]={1,2,3,4,5,6,7,8,9,0};
char *temp;
char data;
temp=get_char(byte_array,10);
data=*temp;
printf("String point %s ",data);
}
Two fixes:
As you want to convert to char, then
array_char[i]=my_byte[i]+0; should be array_char[i]=my_byte[i]+'0'; Note '0' is character (that will be converted to int) instead of numeric 0 (which doesn't do anything).
Also you must free temp pointer in main as that memory is dynamically allocated in get_char() function.
Edit: just notice another issue in your get_char()
char *array_char=(char *) malloc(sizeof(char)*10);
should be
char *array_char= malloc(sizeof(char)*(packetsize+1));
After the for loop, ensure the buffer is NUL-terminated:
array_char[packetsize] = '\0';
Notice that your packetsize is never used - you should get some compiler warning about it. It's bad to hard code 10 in your malloc - it's actually the whole idea of parsing the packetsize as a parameter - so use it properly.
You need to watch out for these things:
You need to add a null-terminating character at the end of *array_char, otherwise using this pointer allocated from the heap will cause undefined behaviour.
You can simply allocate *array_char like this:
char *array_char = malloc(packetsize+1);
As sizeof(char) is 1, and +1 for trailing nullbyte.
You also don't need to cast return of malloc().
Instead of passing 10 as packetsize to get_char(), you should pass this size as sizeof(arr) / sizeof(arr[0], which is the calculated size of the array. This can be a size_t variable declared somewhere or even a macro.
malloc() needs to be checked, as it can return NULL if unsuccessful.
You need to free() temp at some point in the program.
array_char[i]=my_byte[i]+0; needs to be array_char[i]=my_byte[i]+'0'; instead, as '0' is the ascii code for a zero character.
char data needs to be char *data, as temp is a pointer.
If you compile with -Wall -Wextra, you will see that this line:
data=*temp;
Is dangerous, and will trigger warnings of making pointers from integers without a cast. It will most likely lead to a segmentation fault. If temp and data are both pointers, then you can simply use:
data=temp;
Which sets data to the address of temp. Sometimes this is written as data = &(*temp);, but this is harder to read. Although their is no need for data, and using temp alone should be fine.
Your code can then look like this:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define ARRAYSIZE(arr) (sizeof(arr) / sizeof(arr[0]))
char *get_char(int my_byte[], size_t packetsize) {
char *array_char = malloc(packetsize+1);
const char ascii = '0';
size_t i;
if (!array_char) {
printf("Cannot allocate %zu bytes\n", packetsize+1);
exit(EXIT_FAILURE);
}
for(i = 0; i < packetsize; i++) {
array_char[i] = my_byte[i] + ascii;
}
array_char[i] = '\0'; /* or array_char[packetsize] = '\0' */
return array_char;
}
int main(void) {
int byte_array[]={1,2,3,4,5,6,7,8,9,0};
char *temp, *data;
temp = get_char(byte_array, ARRAYSIZE(byte_array));
data = temp;
printf("String point %s\n", data);
printf("String converted into number = %d\n", atoi(data));
free(temp);
temp = NULL;
return 0;
}
You can also look into strtol, which is better than using atoi() in terms of error checking.
It is Not Wise Idea to Return a Array From A Function. So how to return a string then? As most of libc functions use we can use some thing like that (i.e) passing a buffer along with our input and expect function to use output buffer to give us result.
Some issue to take care while coding
write your logic first.
try to use available functions from libc.
while dealing with byte data/binary data be take precaution of buffer overflow.
don't allocate in a function and de-allocate in another function.
Below is Example of your code with modification.
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <stdint.h>
int get_char(uint8_t my_byte[], int packetsize, char *buffer, int max_buffer)
{
int byte_itr, buf_itr;
char temp_buf[16]={0x00};
for(byte_itr=0, buf_itr=0; byte_itr<packetsize && max_buffer > buf_itr; byte_itr++)
{
memset(temp_buf, 0x00, sizeof(temp_buf));
char temp_ch = my_byte[byte_itr];
snprintf(temp_buf, sizeof(temp_buf), "%d", temp_ch);
if( buf_itr+strlen(temp_buf) >=max_buffer){
break;
}else{
buf_itr += strlen(temp_buf);
strcat(buffer, temp_buf);
if(byte_itr+1 < packetsize){
strcat(buffer, ",");
buf_itr += 1;
}
}
}
return buf_itr;
}
int main()
{
uint8_t byte_array[]={1,2,3,4,5,6,7,8,9,0};
char char_array[32]={0x00};
int len = get_char(byte_array, 10, char_array, sizeof(char_array));
printf("String point %s : len %d\n", char_array, len);
}
NOTE:
when length return and size of output buffer same then buffer full condition happened.

Memory error - Simple XOR encryption in C

I am having some memory issues with printing hex in the following format: \xAA\xAB\xDC using my encryption routine.
I did some modifications, using snprintf() and strcat() in an attempt to fix the output and it worked to some degree.
This is the function I originally started out with, which is probably better than my modified version.
char *encrypt(char key, const char *a) {
char *output = malloc(strlen(a)+1);
bzero(output, strlen(a)+1);
strcpy(output, a);
char *tmp = output;
int i;
for (i = 0; tmp[i] != 0; i++) {
tmp[i] = key ^ tmp[i];
}
return output;
}
My current progress is as follows:
char *encrypt(char key, const char *a)
{
char buf[256];
char *tmp = a;
int i;
int *k;
for (i = 0; tmp[i] != 0; i++)
{
char temp[10];
k = key ^ tmp[i];
snprintf(temp, sizeof(temp), "\\x%s", k);
strcat(buf, temp);
}
return buf;
}
int main(int argc, char **argv)
{
if (argv[1] == NULL){
printf("Usage: %s <string>\n", argv[0]);
}
else printf("Encrypted string: %s\n", encrypt(0xEB, argv[1]));
return 0;
}
If anyone could point me in the right direction on how to fix the memory issue, and if the code can be improved I would appreciate that a lot.
The primary issue, in your code, buf is local to the function encrypt(). So you may not return the array from the function. Once the function finishes, the array will cease to exist and the returned address will be invalid. If the returned value is ued in the caller, it will invoke undefined behavior.
You need to define buf as a pointer and allocate dynamic memory using malloc() or family. Also, you need to free() the memory, once the usage is over.
That said,
you have defined k to be a pointer but did not allocate memory to it.
k = key ^ tmp[i]; seems meaningless, maybe you meant *k = key ^ tmp[i];
%s expects a pointer to char array (null-terminated) as argument. From that point, snprintf(temp, sizeof(temp), "\\x%s", k); also looks wrong. What you need is snprintf(temp, sizeof(temp), "\\x%d", *k); to print the int value.
Instead of:
int *k;
k = key ^ tmp[i];
snprintf(temp, sizeof(temp), "\\x%s", k);
use this:
unsigned char k;
k = key ^ tmp[i];
snprintf(temp, sizeof temp, "\\x%02X", k);
Note that you also have other changes to make regarding buf. Firstly you never initialize it, so you are appending to junk. And you never check that you didn't overflow it.
Also you attempt to return this from a function, however, since it is a local variable, it ceases to exist when the function returns.
See this thread for some suggestions of how to get freshly-written string out of a function. You could use malloc(256) in the same vein as your first attempt (and remember to replace sizeof buf with the mallocated length, in the snprintf call).
It'd be more robust to use unsigned char instead of char for both the key and the message. An example of the issues is that on x86 or x64, char has a range of -128 to 127 so when you supply 0xEB (i.e. 235) this is an out-of-range assignment which is not well-defined.
But on common systems you will get away with using char because they tend to define out-of-range assignment by using 2's complement and truncating excess bits, which works in your situation.

How to dynamically allocate a two dimensional array of pointers ? (C)

I have an assignment to make a dictionary.
It will contain an x amount of words and their definitions (input by user).
Instructions say that the dictionary should be of type char*** (2D array of pointers=arrays=strings), but I've got absolutely no idea of how to dynamically allocate the size of the array. it should have 2 lines, 1 for words and another 1 for their definitions, and the number of columns is decided by how many words are in the dictionary. While looking for help online i came up with this:
char** AllocateArray(int line, int column)
{
char** pArray=(char**)malloc(line*sizeof(char*));
int i;
for(i=0;i<2;i++)
pArray[i]=(char*)malloc(column*sizeof(char));
return pArray;
}
What changes should i make in the code for it to work with my char*** ?
Using Visual studio 2012
Edit:
I have a problem with this right now:
void inputString(char* p1)
{
char buffer[80];
printf("\nEnter a word:");
scanf("%s",buffer);
p1=(char*)malloc(strlen(buffer)+1);
if(p1!=NULL)
{
strcpy(p1,buffer);
free(buffer);
}
}
it crashes right after i input a word. the char* that the function receives is dictionary[i][j]. –
Don't free() anything allocated on the stack (i.e. buffer).
Also, your function inputString() will not tell its client what memory it had allocated, since p1 is local to it.
Here is an example.
char*** dictionary;
int i = 0;
int j = 0;
int lines = 10;
dictionary = (char***)malloc(sizeof(char**)*lines);
for(i=0;i<lines;i++)
{
dictionary[i] = (char**)malloc(sizeof(char*)*4);
for(j=0;j<4;j++)
dictionary[i][j] = (char*)malloc(sizeof(char)*25);
}
You have to modify the malloc's parameters in order to adapt to your problem/ or modify them when you need more memory for your strings.
Also it might be a good idea to try and free memory when you do not need it
Don't forget to malloc like this...
dictionary[i][j] = (char*)malloc(sizeof(char)*strlen(word_to_insert)+1);
...because each word end with a supplementary byte filled with 0 "null terminate string".
a sample
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(){
char ***dictionary;
const char *words[] = { "ASEAN", "United Nations", "OPEC" };
size_t howManyWords = sizeof(words)/sizeof(*words);
int i;
dictionary = malloc(howManyWords*sizeof(char**));
printf("Please enter the definition of this word\n");
for(i = 0; i < howManyWords; ++i){
char buff[80];
char **keyValue;
printf("%s : ", words[i]);
fgets(buff, sizeof(buff), stdin);
keyValue = malloc(2*sizeof(char*));
keyValue[0] = (char*)words[i];
keyValue[1] = malloc(strlen(buff)+1);
strcpy(keyValue[1], buff);
dictionary[i] = keyValue;
}
//print
for(i=0;i<howManyWords;++i){
printf("%s : %s", dictionary[i][0], dictionary[i][1]);
}
//release
for(i=0;i<howManyWords;++i){
free(dictionary[i][1]);
free(dictionary[i]);
}
free(dictionary);
return 0;
}

Resources