2010-03-07 67 views
3

我有我製作的結構類型的指針。在程序開始時,它開始爲NULL,然後我再malloc/realloc,因爲我需要添加/刪除這些結構,我只是要用我的指針指向第一個結構,並像數組一樣移動它。嘗試創建指針時,賦值錯誤中的無效左值NULL

當我的malloc/realloc的我總是把「陣列」的大小在存儲器中的一個比它需要更大/面積。我這樣做,所以我可以將內存中的「最後索引」/區域設置爲NULL,所以我可以說while(pointer!= NULL)。

我得到的錯誤:在分配無效的左值當我嘗試分配NULL來與線的存儲陣列/地區的最後一個位置:

// Realloc remotelist by adding one to connrhosts 
    connrhosts++; 
    remotelist = realloc(remotelist, sizeof(rhost)*(connrhosts + 1)); 
    (remotelist + connrhosts) = NULL; 

我想我要說的是:

  • 它的時間,一個新的結構添加到我的數組,所以我會加一connrhosts。
  • realloc的一種指點remotelist到一個新的內存區域是connrhosts(多少結構我會用)以及一個附加空間的大小的內存,所以我可以讓它空
  • 點remotelist到新的內存區域
  • 使用我的指針remotelist並添加偏移connrhosts,它現在將指向內存區域的最後一個索引,並將該指針設置爲NULL。

就我所能說的(或感覺)我所做的一切都是正確的,但是我一直在做這個項目已經有一段時間了,現在我有了隧道視覺的印象。我很想有一個全新的眼睛看看我的邏輯/代碼,讓我知道他們的想法和我做錯了什麼。再次感謝。 :d

編輯 - 我的問題 部分原因是我覺得我有什麼我可以做的指針的誤解。

這裏是我的結構:

typedef struct { 
    char address[128]; // Buffer that holds our address of the remote host 
    int port; // Port of the remote host 
    int conn; // FD to the connection of our remote host 
    int ofiles; // Open files associated with the remote host 
} rhost; 

我希望我所能做的就是遍歷的記憶我的數組/地區,並說如果不爲空,然後用它做什麼。所以我原來的循環語句是while(NULL!= remotelist)。現在我相信閱讀的迴應和評論,這種邏輯是錯誤的,因爲我檢查指針是否爲空?我應該檢查指針指向的內存/結構區域是否爲空?如果是這種情況,它應該像while(NULL!= *(remotelist + someoffset))?

我做這種方式爲我的老師建議它/在課堂上談論它。

我最初聲明/ remotelist的初始化是:rhost的* remotelist = NULL;當LHS是評估表達式,不會成爲可以分配的變量發生

+0

比較順便說一句,爲什麼你在做'++ connrhosts',然後在配置中使用'connrhosts + 1'?那個額外的'+ 1'的目的是什麼? – AnT 2010-03-07 22:50:59

+0

connrhosts是我可以連接的遠程主機的當前數量。我只有兩個索引,0和1,都指向一個結構,我做+1,所以我可以有三個索引,0,1和2,其中0和1指向一個結構,2可以等於NULL。這樣我就可以像while(NULL!= remotelist) – Chris 2010-03-07 22:54:35

+1

這樣的語句。rhost是一個結構。你所做的分配,remoteli st指向的是這些結構的數組*,而不是指針數組。您不能將結構設置爲NULL,因此您需要另一種方式來表示列表的結尾。一種方法是保持整數與計數掛在一起,並將其與指針一起傳遞。另一種方法是使用rhost的一個字段作爲「數據結束」標記,例如說,如果'ofiles'爲-1,則意味着數組的末尾。你可以使用實際的以NULL結尾的指針數組。我不推薦它:你必須分開分配它們。 – 2010-03-07 23:01:51

回答

6

Errornous左值分配。你在做什麼看起來像一個應該在RHS上的操作(指針算術)。

你可以做的是:

remotelist[connrhosts] = NULL; // array notation asuming 
           // remotelist is an array of pointers 

假設connrhosts是intsize_t或者你可以這樣做:

remotelist += connrhost; // pointer arithmetic 
*remotelist = NULL; // assuming remotelist is an array of pointers. 
+0

不會remotelist + = connrhost; //指針運算 * remotelist = NULL; 實際上改變我的指針指向的地址?如果這樣對我來說會是一個問題。我添加了偏移量或連接符,所以我可以說「遠離開始的許多位置都會使NULL」。我還提供了更多關於我的結構和我認爲我在做什麼的文檔。 – Chris 2010-03-07 22:36:56

+0

是的,它通過remotelist類型的connrhost塊增加指針。之後您必須將其移回。我包括兩個選項的完整性。我對下面的答案給出了+1,表明[]符號更清晰 - 它是。 – 2010-03-07 22:42:27

+0

我繼續前進,嘗試使用[]符號,但後來在賦值錯誤中遇到了不兼容的類型。所以我一定在早些時候做錯了什麼,或者我真的不知道我在做什麼? – Chris 2010-03-07 22:44:11

2

您需要derereference終場前*訪問哪些存儲在指針指向的內存。

*(remotelist + connrhosts) = NULL; 
3

您還需要取消引用您的指針。

*(remotelist + connrhosts) = NULL; 

雖然我覺得

remotelist[connrhosts] = NULL; 

更清晰。

0

表達式pointer != NULL引用指針本身,而不是指針引用的內存。即使你可以給它分配NULL,也不能解決問題。

增加指針後,它不是NULL,它有一個地址,它是最後一個額外的struct slot的地址。

你可以,我想,這個區域設置爲0的有:

memset(remotelist + connrhosts, 0, sizeof(rhost)); 

然後,你可以做這樣的事情p->field == 0如果該字段爲0從來沒有一個真正的結構......

就個人而言,如果我理解正確,我會處理這個問題,或者通過爲結構分配第二個指針數組,或者通過跟蹤我擁有的數量,或者很可能通過使用諸如鏈接列表之類的集合或樹,也就是比realloc().

更優雅的擴展操作
0

「內存/結構區域」不能分配爲NULL,不能與NULL進行比較。 NULL僅用於指針。

如果你想設置全部[新分配]結構的字段爲零,在C89/90中常見的成語是= { 0 }初始的幫助下做到這一點:

const rhost ZERO_HOST = { 0 }; 
... 
connrhosts++; 
remotelist = realloc(remotelist, connrhosts * sizeof *remotelist); 
remotelist[connrhosts] = ZERO_HOST; 

或者你可以簡單地使用memset(這是一個黑客)。

至於檢查您的數組中的條目是否是全零...有對於沒有內置的操作,雖然memcmp功能可以幫助

if (memcmp(&remotelist[i], &ZERO_HOST, sizeof ZERO_HOST) == 0) 
    /* All zeroes */; 

(這也是一個黑客位的,雖然少了「hackish」那memset之一)。

但它通常不這樣做。這樣做真的沒有意義。通常情況下,你應該簡單地在你的結構只選擇一個字段(「主」之一),它可以告訴你的結構是否「使用:或不和只是單場0

if (remotelist[i].address[0] == '\0') 
    /* Entry is not used */;