尝试使指针为NULL时,赋值错误中的左值无效

时间:2010-03-07 22:09:21

标签: c compiler-construction pointers compiler-errors

我有一个我所做的结构类型的指针。在程序启动它开始为NULL然后我malloc / realloc因为我需要添加/删除这些结构,我只是使用我的指针指向第一个结构并像数组一样穿过它。

当我使用malloc / realloc时,我总是将内存中“数组”/区域的大小设置为大于它需要的大小。我这样做,所以我可以将内存中的“最后一个索引”/区域设置为NULL,这样我就可以说像while(指针!= NULL)。

我得到错误:当我尝试将NULL分配给内存数组/内存区域中的最后一个位置时,赋值无效:

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

我认为我说的是:

  • 是时候为我的数组添加一个新结构,所以我会将connrhosts增加一个。
  • 将指向remotelist的内存重新分配给一个新的内存区域,该区域的大小是connrhosts(我将使用多少个结构)以及一个额外的空间,所以我可以将其设为NULL
  • 将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;

我希望我能做的是循环遍历我的数组/内存区域,并说如果它不是NULL然后用它做一些事情。所以我的原始循环语句是while(NULL!= remotelist)。现在我相信正在阅读这些逻辑错误的回复和评论,因为我正在检查指针是否为空?我应该检查指针所指向的内存/结构区域是否为空?如果是这种情况,它应该像while(NULL!= *(remotelist + someoffset))?

我正在这样做,因为我的老师在课堂上建议/谈论它。

我对remotelist的初始声明/初始化是:rhost * remotelist = NULL;

5 个答案:

答案 0 :(得分:6)

当LHS是一个不能成为可以分配的变量的求值表达式时,会发生错误的左值赋值。你正在做什么看起来像一个应该在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.

答案 1 :(得分:3)

您还需要取消引用指针。

*(remotelist + connrhosts) = NULL;

虽然我认为

 remotelist[connrhosts] = NULL; 

更清楚。

答案 2 :(得分:2)

您需要使用*取消引用指针,以访问存储在指针寻址的内存中的内容。

*(remotelist + connrhosts) = NULL;

答案 3 :(得分:0)

表达式pointer != NULL指的是指针本身,而不是指针引用的内存。即使您可以为其分配NULL,也无法解决问题。

递增指针后,它不是NULL,它有一个地址,最后一个额外的struct槽的地址。

我想,你可以将这个区域设置为0,用:

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

如果这个字段在真正的结构上从不为0,那么你可以做p->field == 0之类的事情......

就个人而言,我会处理这个问题,如果我理解正确的话,可以通过为结构分配第二个指针数组,或者只跟踪我有多少,或者最有可能通过使用这样的集合来处理作为链接列表或树,即具有比realloc().

更优雅的扩展操作的东西

答案 4 :(得分:0)

“内存/结构区域”无法分配NULL,无法与NULL进行比较。 NULL仅用于指针。

如果你想设置 [新分配的]结构的所有字段为零,在C89 / 90中,常见的习惯用法是在= { 0 }初始值设定项的帮助下完成:< / p>

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