如何在结构上分配内存以便连续进行

问题描述 投票:-1回答:1

我想在内存中形成连续的结构吗?我有这个结构:

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中分配内存,而是在其他地方。那么,如何才能以我想要的方式分配内存?谢谢! :)

c malloc structure dynamic-memory-allocation
1个回答
0
投票

[许多老师没有花时间充分解释为什么字符串需要“指针”而不是仅仅具有字符串。

一个整数是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"qtypeqclass

这就是您需要进行内存操作而不是简单的C / C ++结构的地方。

一种技术是将结构的固定部分放置在[[first

之后,然后是可变字符串。根据您的编译器,可以执行以下操作:struct QUESTION { unsigned short qtype; unsigned short qclass; unsigned char qname[]; };
看看我做了什么?前两个变量的大小已知,因此需要先进行。最后一个变量是一个数组-但大小未知。您不能再使用其他任何变量。请注意,只有最近的编译器允许这样做!较早的编译器允许您使用qname[0]表示“未知大小”-您的编译器可能会抱怨以下任何一个...

假设您可以编译以上内容,现在又遇到了两个问题:

    什么是sizeof(QUESTION)
  1. 如何将实际问题输入qname[]
  2. (1)的答案很明显-但不是您想要的。只是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
© www.soinside.com 2019 - 2024. All rights reserved.