2013-03-24 19 views
0

最近我遇到了C指針的問題。如您所見,我有一個從STDIN讀取數據的循環。問題是我不太明白我所做的。C - 內存分配問題 - 需要說明

我爲這個struct_CONTAINER結構分配了內存。我希望有一個長度爲BUFFER_SIZE的C字符串數組。如果我理解正確,該數組包含BUFFER_SIZE(char *)對象 - 這意味着此數組的權重爲8 * BUFFER_SIZE個字節(每個字符指針最多8個字節)。所以,例如,如果BUFFER_SIZE被定義爲值10,那麼這給了我們80個字節的數組,並且可能整個結構將具有相似的大小。

問題是我能夠遍歷該指針值大於BUFFER_SIZE,什麼是我奇怪的 - 內存不是NULL。我知道在那個循環中,我可能會嘗試訪問其他已分配的內存。但我不確定。如果有人會很好,並告訴我我在做什麼對與錯。內存分配可能太大。提前致謝!

char *item = NULL; 

if(dup2(STDIN_FILENO, fdin) < 0){ 
    perror("dup2()"); 
    exit(errno); 
} 

memset(reading, '\0', BUFFER_SIZE); 

struct struct_CONTAINER{ 
    char *container[BUFFER_SIZE]; 
}; 


while((r_control = read(fdin, reading, BUFFER_SIZE-1)) > 0){ 
    item = &shmemContainer->container[i++]; 
    strcpy(item, reading); 
    memset(reading, '\0', BUFFER_SIZE); 
} 

編輯:我忘了告訴你什麼是containerchar*類型意味着它的字符串數組「項」變量

+1

項目的類型沒有幫助。考慮閱讀@Grijesh Chauhan的答案。 – Aneri 2013-03-24 18:12:23

+0

你是否爲其他地方的「容器」數組所指向的字符串分配內存? – Digikata 2013-03-24 18:24:16

+0

@Digikata你是正確的,這可能是OP的一個額外的錯誤。我添加了你的點在我的回答 – 2013-03-24 18:33:47

回答

1

你的struct成員的類型。您要指派給串char**item地址,並嘗試調用strcpy(item, reading);

您在-至少以下statments之一做錯了。

item = &shmemContainer->container[i++]; 
     ^ is wrong 
strcpy(item, reading); 
     ^or this is wrong 

【答案】爲你評論說第一點是錯誤代碼
因爲precedence of -> operator is higher then &。編譯代碼時應該會收到警告。

  • 如果第一個表達式item = &shmemContainer->container[i++];是錯寫什麼樣子:

    item = (&shmemContainer)->container[i++];

  • 如果strcpy(item, reading);是錯誤進行糾正,如:

    strcpy(*item, reading);

而作爲一世可以從while循環理解你想從fdin讀字符串轉換成字符串數組,你可以這樣做:

while((r_control = read(fdin, reading, BUFFER_SIZE-1)) > 0){ 
    reading[r_control] = '\0'; // null ternimate 
    strcpy(shmemContainer->container[i++],reading) ; 
    memset(reading, '\0', BUFFER_SIZE); 
} 

代碼reading[r_control] = '\0';增加是因爲第一次你缺少memset(),記得read()不會終止\0串它自。

編輯
考慮@ Digikata的評論,因爲你正在做strcpy()container[]確保您爲每個字符串分配內存。

我的建議:

container[]是字符串數組,所以你可以在你的while循環分配內存,如:

i = 0; 
while((r_control = read(fdin, reading, BUFFER_SIZE-1)) > 0){ 
    reading[r_control] = '\0'; // null ternimate 
    shmemContainer->container[i] = malloc(strlen(reading) + 1); 
    strcpy(shmemContainer->container[i++],reading) ; 
    memset(reading, '\0', BUFFER_SIZE); 
} 

新增的內存分配,如果你缺少。

+0

對不起,我忘了指定「item」變量的類型。它是 char * item;這是我的數組中的單個c字符串; 我正在做一些其他的操作,我想縮短一點。 整個代碼的作品,但我很驚訝,我可以訪問其長度的數組項目,並在內存中的位置不爲null – Garet 2013-03-24 18:14:54

+0

@Kuntaker我已經在我的答案中提到這一點。如果你的'item'是'char *'類型,那麼'item =&shmemContainer-> container [i ++];'是錯誤的,或者添加'()'或者改變你的while循環。 – 2013-03-24 18:18:36

+0

讓我解釋一下我是如何理解的,如果你糾正我的錯誤 1.運算符「 - >」>「&」運算符,所以首先即時訪問'shmemContainer'的成員 ,它是'容器'。 2.然後用運算符「[]」即時通訊獲取值指針指向 (我不知道這裏) 3.因爲我需要該指針的地址,所以即時獲取與運算符 4.最後im把這個地址分配給(char *)指針 ,比如'item =&shmemContainer-> container [i ++];' – Garet 2013-03-24 18:44:12

0

C不會阻止您索引超過預期的內存位置。例如:

char astring[5] = "0123"; // there is a zero at index 4 
char* ptr = astring;  // ptr[4] == 0 

printf("%c", ptr[5]); // reads a byte beyond the end of the string array 

你的代碼需要在邏輯上防止發生,頻繁出現的數據有, 但寫它(有時甚至是閱讀它)會導致不確定的行爲。因此,在您的代碼中,容器之外的區域讀取爲非空值是正常的。

順便說一句,從你的問題來看,你是否理解了指向c字符串的char *類型與分配的內存區域(例如上面代碼中的「ptr」「astring」變量)之間的區別。您的示例代碼不會爲該字符串分配任何內存。