Reputation: 395
I am trying to define an array using pointer instead of size declaration because I do not know how many elements a map might have. Tried linked list but was not successful. I am sorry if this is a report. I am a newbie please excuse if it looks like a stupid question.
#include<stdio.h>
typedef struct _keyValue
{
char *key;
char *value;
} _keyValue;
typedef struct _keyValues
{
/* _keyValue keyValue[5]; - This works*/
_keyValue *keyValue;
int size;
} _keyValues;
_keyValues map;
main()
{
map.keyValue[0].key = "Key One";
map.keyValue[0].value = "Value One";
map.keyValue[1].key = "Key Two";
map.keyValue[1].value = "Value Two";
map.size = 2;
printf("Key: %s Value: %s", map.keyValue[0].key, map.keyValue[0].value);
}
Upvotes: 3
Views: 374
Reputation: 40155
#include <stdlib.h>
int main(void){
map.size = 2;
map.keyValue = malloc(sizeof(_keyValue)*map.size);
map.keyValue[0].key = "Key One";
map.keyValue[0].value = "Value One";
map.keyValue[1].key = "Key Two";
map.keyValue[1].value = "Value Two";
printf("Key: %s Value: %s", map.keyValue[0].key, map.keyValue[0].value);
return 0;
}
if I do not know the size
#include <stdlib.h>
#include <string.h>
int main(void){
char buff[128] = "";
map.size = 5;//decide the size temporarily
map.keyValue = malloc(sizeof(_keyValue)*map.size);
int count = 0, retv;
while(1){
printf("input key : ");
retv=scanf(" %127s", buff);
if(retv != 1 || strcmp(buff, "end")==0) break;
map.keyValue[count].key = strdup(buff);
printf("input value : ");
scanf(" %127s", buff);
map.keyValue[count].value = strdup(buff);
++count;
if(count == map.size)//full
map.keyValue = realloc(map.keyValue, sizeof(_keyValue)*(map.size+=5));//increase the size
}
int i;
for(i=0;i<count;++i)
printf("Key: %s Value: %s\n", map.keyValue[i].key, map.keyValue[i].value);
//dealloc
for(i=0;i<count;++i){
free(map.keyValue[i].key);
free(map.keyValue[i].value);
}
free(map.keyValue);
return 0;
}
Upvotes: 1
Reputation: 7458
If you don't know how big they will be, then use dynamic allocation. Key functions here are malloc and free.
Here's a suggestion on how you can use your structs if you don't know how big they will be:
First have the following includes in your code:
#include <stdio.h> /* for printf */
#include <string.h> /* for strcpy, as you cannot directly assign strings to a malloc'd pointer */
#include <stdlib.h> /* for malloc and free, for managing memory dynamically */
Then we define the size of the keys and values:
const int key_size = 10; /* let's define how big our keys and values will be */
const int value_size = 25;
And here is how you can use your structs:
map.size = 30; /* decide how many keyValues we will have */
map.keyValue = malloc(sizeof(_keyValue) * map.size); /* create storage big enough for 30 _keyValue structs
* malloc will allow you to assign memory to key and treat it as an array
* malloc assigns memory from the heap
* equal to the size specified (30),
* this can be potentially as large as your computer's memory */
map.keyValue[0].key = malloc(sizeof(char) * key_size); /* let's create a key at position 0 */
strcpy(map.keyValue.key, "some key"); /* copying some values into key */
map.keyValue[0].value = malloc(sizeof(char) * value_size); /* let's create some space for a value for the 0th element */
strcpy(map.keyValue.value, "some value");
... /* you process and work with those values as you see fit */
free(map.keyValue[0]) /* malloc assigned memory needs to be returned to the OS as it's manually managed,
* here we free the element at position 0 we created earlier
* if you have more than element here use a loop e.g:
* for (int i = 0; i < map.size; i++) { free(map.KeyValue[i]) }
*/
free(map.keyValue); /* free the keyValue itself that stored all the keyValue structs*/
One tip, declarations starting with an underscore are discouraged as they are reserved for the language.
Upvotes: 2
Reputation: 42205
map.keyValue
in your example is an uninitialised pointer. You need to provide storage for the array by allocating memory using malloc
main()
{
map.keyValue = malloc(sizeof(*map.keyValue) * 2);
map.size = 2;
map.keyValue[0].key = "Key One";
map.keyValue[0].value = "Value One";
You can later extend the array using realloc
int newMapSize = ...
_keyValue* temp = realloc(map.keyValue, sizeof(*map.keyValue) * newMapSize);
if (temp == NULL) {
/* allocation failed. Handle out of memory error and exit */
}
map.keyValue = temp;
map.size = newMapSize;
// map.keyValue[0..newMapSize-1] are now available
Upvotes: 5