2013-06-11 222 views
3

我想定義一個數組使用指針而不是大小聲明,因爲我不知道有多少個地圖可能有的元素。嘗試鏈接列表,但沒有成功。如果這是一份報告,我很抱歉。如果看起來像一個愚蠢的問題,我是新手請原諒。C結構與結構指針

#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); 
} 
+0

請勿使用以下劃線開頭的名稱;它們基本上被保留以供「實施」使用。 –

+0

另外,更具體的問題; 「嘗試鏈接列表但沒有成功」沒有提供足夠的信息讓某人回答你的問題。 –

回答

2

如果你不知道他們將會有多大,然後使用動態分配。這裏的主要功能是mallocfree

下面是關於如何使用您的結構,如果你不知道他們有多大是一個建議:

首先有以下的代碼包括:

#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 */ 

然後我們定義鍵和值大小:

const int key_size = 10; /* let's define how big our keys and values will be */ 
const int value_size = 25; 

這裏是你如何使用您的結構:

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*/ 

一個技巧,以下劃線開頭的聲明因爲它們爲語言保留而不鼓勵。

+1

+1用於分配keyValue.key和keyValue.value變量。 –

5

map.keyValue在你的例子中是一個未初始化的指針。您需要爲數組分配的內存使用malloc

main() 
{ 
    map.keyValue = malloc(sizeof(*map.keyValue) * 2); 
    map.size = 2; 

    map.keyValue[0].key  = "Key One"; 
    map.keyValue[0].value = "Value One"; 

以後,您可以延長使用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 
+0

非常感謝。感謝快速回復。 –

+0

如果您要在重新分配內存時使用此方法,則標準實現是在需要更多空間時將元素數加倍。 –

+1

是的,一種常用的方法是在每次realloc()時將存儲空間加倍。其他常見方法是將存儲容量增加1.5倍,或者增加固定或滑動數量的元素。在任何特定情況下哪種策略最好,可能取決於多種因素,如您的存儲使用速度,增長率,元素多大。在某些情況下,甚至可能最好實施這些策略中的一種以上,並在運行時間之間進行選擇。 –

1
#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; 
} 

陣列提供存儲,如果我不知道大小

#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; 
} 
+0

您的建議代碼看起來正確,但是對於已更改內容的更多解釋以及爲什麼會使OP更有價值。 – simonc

+0

如果我不知道地圖的大小,並使用循環來填充值,該怎麼辦? –

+1

@MeUnagi你和我(;-p)有一個很好的解釋simonc。如果預先確定尺寸未知,您可以通過'realloc'擴展目前確保的區域。 – BLUEPIXY