我想在内存中形成连续的结构吗?我有这个结构:
struct QUESTION
{
unsigned char *qname;
unsigned short qtype;
unsigned short qclass;
};
并且我想将* qname分配为字符串,并且我也希望qtype和qclass在* qname字符串之后才在内存中。我需要将其保存到缓冲区:
unsigned char buf[65536];
struct QUESTION *qu = NULL;
qu = (struct QUESTION *)&buf;
而且我需要确保它按此顺序在缓冲区中:完全* qname字符串,qtype和qclass。我的问题是,我认为,当我为* qname分配内存(使用malloc())时(我必须做,因为我需要在其中放置字符串),它不会在buf中分配内存,而是在其他地方。那么,如何才能以我想要的方式分配内存?谢谢! :)
[许多老师没有花时间充分解释为什么字符串需要“指针”而不是仅仅具有字符串。
一个整数是4个字节(或2,或8,取决于计算机)。浮点值为6个字节(或4,或8,也取决于)。问题是,字符串没有已知的字节数。无论是"Hi!"
还是"My name is Inigo Montoya"
,您都不知道字符串在编译时有多长。因此,要存储字符串或将一个字符串传递给函数,您不能这样做。相反,您将其放在somewhere other,然后对该字符串使用pointer-这就是*
的含义。
A char *
是指向字符串的first字符的指针。按照惯例,每个字符after也是字符串的一部分-直到到达NUL
。其值为0
-与'0'
不同。您希望字符串能够保存电话号码("The phone number is 1-800-800-8000"
),因此您需要能够存储'0'
(其值为48
)。 NUL
的字面值为0
-作为char
,写为'\0'
。幸运的是,编译器会为您在每个字符串的末尾添加NUL
。
所以您有一个字符串;说const char question[] = "What do you get when you multiply six by nine?"
。看看我如何将question
声明为数组?许多老师说您应该将其声明为const char *
(或const char * const
),但这是错误的!为什么?如果声明const char * const hi = "Hi!"
,则声明的是四个字节来保存值'H'
,'i'
,'!'
和'\0'
的某个地方或其他地方,然后是四个more] >字节存储指向它们的指针,称为hi
!那不是您想要的。
现在,question
位于(例如)0x1000
的内存中。指向该字符串的任何指针的大小都恰好是4个字节(或2或8 ...)-但它们都包含值0x1000
。您的QUESTION
结构具有指向该字符串的指针,因此QUESTION
为4个字节,外加两个批次的2个字节(short
为2个字节),总共为8
您想要
是一个包含以下内容的大型结构:["What do you get when you multiply six by nine?\0"
qtype
qclass
这就是您需要进行内存操作而不是简单的C / C ++结构的地方。
一种技术是将结构的固定部分放置在[[first
之后,然后是可变字符串。根据您的编译器,可以执行以下操作:struct QUESTION
{
unsigned short qtype;
unsigned short qclass;
unsigned char qname[];
};
看看我做了什么?前两个变量的大小已知,因此需要先进行。最后一个变量是一个数组-但大小未知。您不能再使用其他任何变量。请注意,只有最近的编译器允许这样做!较早的编译器允许您使用qname[0]
表示“未知大小”-您的编译器可能会抱怨以下任何一个...
假设您可以编译以上内容,现在又遇到了两个问题:
sizeof(QUESTION)
?qname[]
?4
-两个short
的大小。这是有道理的,因为您没有给出数组的大小。因此,如果使用malloc()
,则需要同时指定QUESTION
的大小plus
question
的大小:QUESTION *q = (QUESTION *)malloc(sizeof(QUESTION) + strlen(question) + 1);
看看我在这里做了什么?我要求malloc()
为QUESTION
结构分配足够的内存,plus
question
的长度,plus的最后一个NUL
]。然后您可以执行以下操作:q->qtype = PHILOSOPHICAL;
q->qclass = FUNNY;
但是要把问题本身放入q
,您需要将字节从0x1000
移到q
指向的位置:
strcpy(q->qname, question);
将在正确的位置将字符从question
复制到q
-包括最后的NUL