这段代码中指针算法的意图是什么?

时间:2016-02-05 00:27:57

标签: c

以下示例中的这一行代码newnode -> item.string = (char *)newnode + sizeof(log_t);是什么?

int nodesize = sizeof(log_t) + strlen(data.string) + 1;
newnode = (log_t *)malloc(nodesize);
if (newnode == NULL) return -1;

// What is this line doing:
newnode -> item.string = (char *)newnode + sizeof(log_t);

strcpy(newnode -> item.string, data.string);

其中newnodelog_t类型的变量(log_t有一个名为item的{​​{1}}类型的变量。 data_t有一个属性data_t

此代码是否设置了字符串的缓冲区大小?

3 个答案:

答案 0 :(得分:1)

newnode -> item.string = (char *)newnode + sizeof(log_t);

右侧将使用指针newnode,将其转换为字符指针,然后将对象的大小添加到其中。

这会在[{1}}之后指定n个字节,其中newnoden对象的大小。

然后将此指针值放入log_t指向的对象的string成员的item成员中。

如果没有看到实际使用的结构,就很难说为什么这样做了,但我最好的猜测是提供一个有效的自引用指针。

换句话说,newnode中的指针将指向newnode本身的实际部分,或者指定的包含newnode对象的更大内存块的一部分它的开始。并且,由于您声明newnode属于newnode类型,因此必须是后一种情况(类型不能包含自身的副本 - 它可以包含指针到类型本身但不是实际副本。)

这可能派上用场的一个例子是对象分配,其中小尺寸完全由对象本身满足,但较大的尺寸处理方式不同,例如使用log_t - 至 - int地图条目:

string

如果您想用500个字符的字符串填充typedef struct { int id; char *string; } hdr_t; typedef struct { hdr_t hdr; char smallBuff[31]; } entry_t; 变量,您可以单独分配字符串,然后设置entry_t指向它。

但是,对于不超过30个字符的字符串,您可以在string中创建它,然后将smallBuff设置为指向该字符串(不需要单独的内存)。这将通过以下方式完成:

string

上面示例中的第三行非常类似于代码中的内容。

同样(可能更适合您的情况),您可以分配比您需要更多的内存并使用它:

entry_t *entry = malloc (sizeof (*entry)); // should check for NULL.
entry->hdr.id = 7;
entry->hdr.string = (char*)entry + sizeof (hdr_t);
strcpy (entry->hdr.string, "small string");

答案 1 :(得分:1)

我假设为newnode的内存分配了字符串的额外空间。

结果是一样的,但我个人将其写为newnode->item.string = (char*) &newnode[1];

也就是说,string的存储空间紧跟在log_t对象之后。这有时在事先分配了一块内存时完成,对象及其成员都指向此块中的内存。过去已经完成了减少小内存分配的开销。

如果log_t是32个字节,并且字符串是16个字节长(包括nul终结符!),则可以使用malloc 48个字节,将字符串成员指向此内存分配的第32个字节,并将字符串复制到那里。

答案 2 :(得分:0)

它正在做指针运算。在C中,当您向指针添加值时,它会将指针移动该值*指针指向的类型的大小。

这样做是将newnode转换为char *,以便假设newnode是char *来完成指针算术,因此它指向的数据大小为1.它们添加了sizeof(log_t)这是log_t类型的大小。根据您对log_t的描述,它看起来像包含一个char *,因此它的大小将是指针的大小,4或8字节,具体取决于体系结构。

因此,这将在newnode包含的地址之后将newnode.item.string设置为sizeof(log_t)个字节。