为列表节点分配内存的安全方法 [英] safe way of allocating memory for a list node

查看:77
本文介绍了为列表节点分配内存的安全方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在一个简单列表中,例如:

In a simple list, ex :

struct Node {  
    Node *next;  
    void *data;  
}  

如果我在一次分配中分配Node和Data(假设我知道大小),是否会出现任何问题,例如

is there any problem if i allocate Node and Data in a single allocation (provided i know the size), like

Node * t = (Node*)malloc(sizeof(Node) + DataSize));  

并且始终在分配的块的末尾分配数据,

and always assign data at the end of allocated chunk,

t->data = (BYTE*)t+ sizeof(Node); /* BYTE is byte length, can use char in gcc */

节点和数据将一口气删除,因此(通过设计)将它们耦合起来并没有真正的问题

Node and data will get deleted in a sinlge go, so there no real problem tighlty coupling them (by design )

我正在查看可移植性问题(特别是包装问题)或其他未知问题?

I am looking at Portability issues (specifically with Packing) or other unknown issues ?

这种分配方式安全且可移植吗?

Is this way of allocation safe and portable ?

推荐答案

正如直言不讳地说,不要在C中写出malloc()的返回值,这样做是没有用的,并且会隐藏错误.

As dirkgently said, don't case the return of malloc() in C, doing so is useless and can hide errors.

另外,为了计算Node头后面的地址,我发现这样做更干净:

Also, to compute the address following the Node header, I find it cleaner to do it like this:

t->data = t + 1;

这是有效的,因为t是类型化的指针,因此对其进行算术运算很好.加1将其增加指向数据的大小,在这种情况下为sizeof (Node).在这种特殊情况下,我发现这种用法是惯用的,它是在紧随malloc()之后的内容之后立即计算地址(当某物"是一个定义明确的类型且具有静态已知的大小时,在这种情况下为Node结构,当然).

This works because t is a typed pointer, so arithmetic on it works fine. Adding one increments it by the size of the pointed-to data, i.e. sizeof (Node) in this case. I find this usage idiomatic for this particular case, of computing the address immediately following something just malloc()ed (when that "something" is a well-defined type with a statically known size, as the Node struct in this case, of course).

这具有以下好处:

  • 类型名称不重复.
  • 没有sizeof,所以更短.
  • 再次,没有演员.
  • 涉及的算术非常简单,易于阅读.
  • No repetition of the type name.
  • No sizeof, so shorter.
  • Again, no cast.
  • Very simple arithmetic involved, easy to read.

我意识到在正确声明Node类型之前,使用它也会出错.我不同意dirkgently的解决方案,这是它在C语言中的外观:

I realized there's an error with your use of the Node type before it's properly declared, too. I don't agree with dirkgently's solution, here's how it should look, in C:

/* This introduces the type name "Node", as an alias for an undefined struct. */
typedef struct Node Node;

struct Node {
  Node *next; /* This is OK, the compiler only needs to know size of pointer. */
  void *data;
};

为了完整起见,由于我从不厌倦地展示我认为应如何编写这样的代码,因此下面是一个函数示例,该函数创建一个新节点来保存n个字节的数据:

For completeness, and since I never tire of showing how I consider code like this should be written, here's an example of a function to create a new node to hold n bytes of data:

Node * node_new(size_t n)
{
  Node *node;

  if((node = malloc(sizeof *node + n)) != NULL)
  {
    node->next = NULL;
    node->data = node + 1;
  }
  return node;
}

就是这样.请注意,在malloc()调用中的指针目标上使用了sizeof,以避免重复类型名称,并且在类型发生更改时也易于忘记.

That's it. Note use of sizeof on the pointer target in the malloc() call, to avoid repeating the type name and making an easy-to-forget dependency if the type should ever change.

这篇关于为列表节点分配内存的安全方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆