Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 指针和内存池分配的误解_C_Pointers - Fatal编程技术网

C 指针和内存池分配的误解

C 指针和内存池分配的误解,c,pointers,C,Pointers,我很难理解下面代码的正确实现。我试图实现一个非常基本的内存池,让用户能够从该池中“创建”对象 使用“buf”进行联合的一个目标是能够轻松地对字节流进行searilize或读取原始Msg #include <stdio.h> #include <stdint.h> // This is the object that everyone will create/use struct Msg { union { // Unique msg id for users

我很难理解下面代码的正确实现。我试图实现一个非常基本的内存池,让用户能够从该池中“创建”对象

使用“buf”进行联合的一个目标是能够轻松地对字节流进行searilize或读取原始Msg

#include <stdio.h>
#include <stdint.h>
// This is the object that everyone will create/use
struct Msg {
  union {
    // Unique msg id for users to do something based on id
    uint16_t msg_type;
    // Data right now is a fixed length of 8 bytes but if I wanted to 
    // change this requirement I could easily since we are allocating 
    // from a memory pool
    uint8_t* data;
  };
  // This is the pointer to the next spot in the memory pool.
  uint8_t* buf;
};

int main() {
  uint8_t memory_pool[100];
  // Somewhere in user code
  struct Msg* msg_ptr;
  // This doesnt work! Throws a seg fault.
  msg_ptr->buf = &memory_pool[0];
  // I thought by setting where buf points to I could something like
  msg_ptr->msg_id = 1234;
  msg_ptr->data[0] = 100;
  // And so on
  // The real implementation would have the user call something like below, where
  // my_memory_pool_get would assign 'buf' to the next available spot in the memory_pool
  my_memory_pool_get(msg_ptr)
  
  // Now if I make Msg.msg_id a pointer to a 16 bit int
  // uint16_t* msg_id
  // The above code works just have to do something like:
  struct Msg msg;
  msg.buf = &memory_pool[0];
  *msg.msg_id = 1234;
  if (*msg.msg_id == 1234) { }
}
  
  
#包括
#包括
//这是每个人都将创建/使用的对象
结构味精{
联合{
//用于用户根据id执行操作的唯一消息id
uint16消息类型;
//现在的数据是8字节的固定长度,但如果我想
//我可以很容易地更改此要求,因为我们正在分配
//从内存池
uint8_t*数据;
};
//这是指向内存池中下一个位置的指针。
uint8_t*buf;
};
int main(){
uint8_t内存池[100];
//用户代码中的某个地方
结构消息*Msg_ptr;
//这不起作用!抛出一个seg故障。
msg_ptr->buf=&内存池[0];
//我想通过设置buf指向的位置,我可以
msg_ptr->msg_id=1234;
msg_ptr->data[0]=100;
//等等
//真正的实现将让用户调用如下所示,其中
//我的内存池会将“buf”分配给内存池中的下一个可用位置
我的\u内存\u池\u获取(msg\u ptr)
//现在如果我将Msg.Msg_id设为指向16位int的指针
//uint16\u t*msg\u id
//以上代码只需执行以下操作:
结构味精;
msg.buf=&内存池[0];
*msg.msg_id=1234;
如果(*msg.msg_id==1234){}
}

您尚未为msg_ptr分配任何内存,因此当您访问
msg_ptr->buf
时,它当然会崩溃,因为msg_ptr是指向内存中尚未分配的某个对象的指针

struct Msg* msg_ptr; 
// This doesnt work! Throws a seg fault.
msg_ptr->buf = &memory_pool[0];  
以下内容不会崩溃,因为msg不是指针。msg在堆栈上分配

// Now if I make Msg.msg_id a pointer to a 16 bit int
// uint16_t* msg_id
// The above code works just have to do something like:
struct Msg msg;
msg.buf = &memory_pool[0];
*msg.msg_id = 1234;
if (*msg.msg_id == 1234) { }
您可能希望函数
my\u memory\u pool\u get(msg\u ptr)
的编写方式如下:

Msg* my_memory_pool_get(){
    int offset = 0;

    // Calculate the position/offset and make sure there is room!
    int room = ... // figure out how to determine is there is room in the buffer.
    if (!room)
        return NULL;

    return &memory_pool[offset];
}

如果您打开警告(gcc也需要优化),编译器几乎肯定会警告您未初始化使用了
msg\u ptr
。我不知道与msg*my\u memory\u pool\u get()有什么不同在数组中返回指向索引的指针与我的实现在main中执行所有操作相比?my_memory\u pool\u get是一个函数,您还没有为其提供实现。我只是建议您如何实现它。再次查看您的代码,Msg中没有任何内容可以告诉您数据的长度。所以你不知道一条消息从哪里开始,另一条消息从哪里结束。我认为你需要进一步思考,更新你的问题,了解你真正想要的是什么。