c - 对指针和内存池分配的误解
问题描述
我很难理解下面代码的正确实现。我正在尝试实现一个非常基本的内存池,并让用户能够从池中“创建”对象。
与“buf”进行联合的一个目标/目标是能够轻松地从字节流中海化或读取原始消息。
#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) { }
}
解决方案
您尚未为 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 不是指针。味精在堆栈上分配。
// 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_memory_pool_get(msg_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];
}
推荐阅读
- javascript - 将 Axios 方法转换为 Fetch
- c# - 在 Bingo 中跟踪选定的数字
- python - 如何使用 Python 3 编写一个不错的 try/except 组件,如果两个输入之一出错则停止
- javascript - 如果拖动,防止单击事件
- sql - 如何控制基于 DB2s 结构的 SQL 语句的执行?
- plugins - 此插件仅适用于页面
- ios - 无法为 iOS 构建应用程序,“无法写入模块会话文件 Session.modulevalidation 没有这样的文件或目录”
- python - Django LayerMapping:如何在保存到数据库之前过滤形状文件
- c# - Visual Studio/Xamarin 找不到与给定名称匹配的 rsc
- time-complexity - 如何计算这部分代码的最坏情况时间复杂度