以下示例中的这一行代码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);
其中newnode
是log_t
类型的变量(log_t
有一个名为item
的{{1}}类型的变量。 data_t
有一个属性data_t
。
此代码是否设置了字符串的缓冲区大小?
答案 0 :(得分:1)
newnode -> item.string = (char *)newnode + sizeof(log_t);
右侧将使用指针newnode
,将其转换为字符指针,然后将对象的大小添加到其中。
这会在[{1}}之后指定n
个字节,其中newnode
是n
对象的大小。
然后将此指针值放入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)
个字节。