2010-03-07 47 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 */;