来自MSVC实施的示例:
#define offsetof(s,m) \
(size_t)&reinterpret_cast<const volatile char&>((((s *)0)->m))
// ^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
可以看出,它取消引用空指针,通常会调用未定义的行为.这是规则的例外还是正在发生的事情?
在查看Linux内核的双链循环列表的实现时,我发现了以下宏:
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
Run Code Online (Sandbox Code Playgroud)
这种方式的工作方式是返回指向结构的指针,只给出其成员之一的地址:
struct blabla
{
int value;
struct list_head *list;
}
Run Code Online (Sandbox Code Playgroud)
因此,只有指向list的指针,你才可以获得指向blabla的指针(并获得"value").对于我的问题,我如何使其尽可能便携(符合C89/C99的最佳情况?).由于使用了typeof(),这只是gcc.
这是我到目前为止所得到的:
#define container_of(ptr, type, member) ( \
(type *) (char *)(ptr)-offsetof(type,member)\
)
Run Code Online (Sandbox Code Playgroud)
此代码段是否符合ISO标准(因此应该能够在任何符合标准的编译器上编译)?
我创建了一个链表.一切正常.
我只是想知道我的代码是否有任何潜在危险.我关注的代码片段是我的推送,弹出和清理.代码的各个部分仅供用户交互,因此不是很重要(无论如何我都发布了,以便我在做什么时更清楚).只是链表应用程序.
非常感谢任何建议,因为这是我的第一次尝试.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct product_data product_data_t;
struct product_data
{
int product_code;
char product_name[128];
int product_cost;
product_data_t *next;
};
static product_data_t *head = NULL;
static product_data_t *tail = NULL;
static product_data_t *new_product = NULL;
// Push a product on to the list.
void push(int code, char name[], int cost);
// Pop (delete) a product from the list.
void pop(int code);
// Display all product in the list.
void display_list();
// Delete all memory allocated …Run Code Online (Sandbox Code Playgroud) 我正在努力使链表与此类似:
那就是在另一个结构中让我首先调用它的"头".但是我发现做了那个改变.难以将值添加到list_item结构中.我尝试了一些事情,看它是否有效.它编译,但是当我运行代码时它会崩溃.任何帮助在这里都会有所帮助.我知道崩溃的原因是我想将new_node指向linked_list.
#include <iostream>
using namespace std;
struct list_item
{
int key;
int value;
list_item *next;
};
struct list
{
struct list_item *first;
};
int main()
{
list *head;
list *new_node;
head = NULL;
head->first = NULL;
for(int i = 0; i < 10; i++)
{
//allocate memory for new_node
new_node = (list*)malloc(sizeof(list));
new_node->first = (list_item*)malloc(sizeof(list_item));
//adding the values
new_node->first->key = i;
new_node->first->value = 10 + i;
//point new_node to first;
new_node->first->next = head->first;
//point first to new_node;
head->first …Run Code Online (Sandbox Code Playgroud)