当前位置: 首页 > news >正文

将Nginx源码数组结构(ngx_array.c)和内存池代码单独编译运行,附代码

在上面一篇的基础上把Nginx源码数组结构也摘录下来,也增加了测试代码,编译运行。
https://blog.csdn.net/katerdaisy/article/details/132358883
《将nginx内存池代码单独编译运行,了解nginx内存池工作原理,附代码》

在这里插入图片描述

核心代码:

//在内存数组中分三次写入 "hello", "world", "!",然后使用指针加偏移,地址加数据长度两种方式将保存在数组中的文字打印出来
// char mychar[6] = "hello";
// ngx_str_t mydata = {sizeof(mychar),mychar};
ngx_array_t *a = NULL;
a = ngx_array_create(pool, 1, sizeof(ngx_str_t));ngx_str_t *s = ngx_array_push(a);
s->data = "hello";
s->len = sizeof(s->data);
printf("a->nelts: %ld, a->nalloc:%ld\n",a->nelts,a->nalloc);
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts))->data);
printf("ngx_array_push:%s\n",s->data);ngx_str_t *s1 = ngx_array_push(a);
s1->data = "wrold";
s1->len = sizeof(s1->data);
printf("a->nelts: %ld, a->nalloc:%ld\n",a->nelts,a->nalloc);
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts+sizeof(ngx_str_t)))->data);//地址加数据长度
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts)+1)->data); //使用指针加偏移
printf("ngx_array_push:%s\n",s1->data);ngx_str_t *s2 = ngx_array_push(a);
s2->data = "!";
s2->len = sizeof(s2->data);
printf("a->nelts: %ld, a->nalloc:%ld\n",a->nelts,a->nalloc);
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts+sizeof(ngx_str_t)*(a->nelts-1)))->data);//地址加数据长度
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts)+a->nelts-1)->data); //使用指针加偏移
printf("ngx_array_push:%s\n",s2->data);

结果:

在这里插入图片描述

完整代码:

//-------------------------------------------------------------------------------------------
//下面是一些头文件和宏定义,从nginx的源码中摘录过来
#include </usr/include/stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdarg.h>
#include <stddef.h> /* offsetof() /
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <signal.h>
#include <pwd.h>
#include <grp.h>
#include <dirent.h>
#include <glob.h>
#include <sys/vfs.h> /
statfs() */

#include <sys/uio.h>
#include <sys/stat.h>
#include <fcntl.h>

#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/resource.h>
#include <sched.h>

#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h> /* TCP_NODELAY, TCP_CORK */
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/un.h>

#include <time.h> /* tzset() /
#include <malloc.h> /
memalign() /
#include <limits.h> /
IOV_MAX /
#include <sys/ioctl.h>
#include <crypt.h>
#include <sys/utsname.h> /
uname() */

#include <dlfcn.h>

#ifndef ngx_inline
#define ngx_inline inline
#endif

typedef int ngx_fd_t;
typedef intptr_t ngx_int_t;
typedef uintptr_t ngx_uint_t;
typedef intptr_t ngx_flag_t;
typedef struct ngx_module_s ngx_module_t;
typedef struct ngx_conf_s ngx_conf_t;
typedef struct ngx_cycle_s ngx_cycle_t;
typedef struct ngx_pool_s ngx_pool_t;
typedef struct ngx_chain_s ngx_chain_t;
typedef struct ngx_log_s ngx_log_t;
typedef struct ngx_open_file_s ngx_open_file_t;
typedef struct ngx_command_s ngx_command_t;
typedef struct ngx_file_s ngx_file_t;
typedef struct ngx_event_s ngx_event_t;
typedef struct ngx_event_aio_s ngx_event_aio_t;
typedef struct ngx_connection_s ngx_connection_t;

ngx_uint_t ngx_pagesize;
ngx_uint_t ngx_pagesize_shift;
ngx_uint_t ngx_cacheline_size;

// #define NGX_LOG_STDERR 0
// #define NGX_LOG_EMERG 1
// #define NGX_LOG_ALERT 2
// #define NGX_LOG_CRIT 3
// #define NGX_LOG_ERR 4
// #define NGX_LOG_WARN 5
// #define NGX_LOG_NOTICE 6
// #define NGX_LOG_INFO 7
// #define NGX_LOG_DEBUG 8

// #define NGX_LOG_DEBUG_CORE 0x010
// #define NGX_LOG_DEBUG_ALLOC 0x020
// #define NGX_LOG_DEBUG_MUTEX 0x040
// #define NGX_LOG_DEBUG_EVENT 0x080
// #define NGX_LOG_DEBUG_HTTP 0x100
// #define NGX_LOG_DEBUG_MAIL 0x200
// #define NGX_LOG_DEBUG_STREAM 0x400

/*

  • do not forget to update debug_levels[] in src/core/ngx_log.c
  • after the adding a new debug level
    */

#define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE
#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_STREAM
#define NGX_LOG_DEBUG_CONNECTION 0x80000000
#define NGX_LOG_DEBUG_ALL 0x7ffffff0

#ifndef NGX_PALLOC_H_INCLUDED
#define NGX_PALLOC_H_INCLUDED

#ifndef NGX_ALIGNMENT
#define NGX_ALIGNMENT sizeof(unsigned long) /* platform word */
#endif

#define NGX_OK 0
#define NGX_ERROR -1
#define NGX_AGAIN -2
#define NGX_BUSY -3
#define NGX_DONE -4
#define NGX_DECLINED -5
#define NGX_ABORT -6
#define NGX_INVALID_FILE -1
#define NGX_FILE_ERROR -1

#define ngx_errno errno
#define ngx_close_file close
#define ngx_close_file_n “close()”
typedef int ngx_err_t;
#define NGX_ENOENT ENOENT
#define ngx_delete_file_n “unlink()”

/*

  • NGX_MAX_ALLOC_FROM_POOL should be (ngx_pagesize - 1), i.e. 4095 on x86.
  • On Windows NT it decreases a number of locked pages in a kernel.
    */
    #define NGX_MAX_ALLOC_FROM_POOL (ngx_pagesize - 1)

#define NGX_DEFAULT_POOL_SIZE (16 * 1024)

#define NGX_POOL_ALIGNMENT 16
#define NGX_MIN_POOL_SIZE
ngx_align((sizeof(ngx_pool_t) + 2 * sizeof(ngx_pool_large_t)),
NGX_POOL_ALIGNMENT)

typedef void (*ngx_pool_cleanup_pt)(void *data);

typedef struct ngx_pool_cleanup_s ngx_pool_cleanup_t;

struct ngx_pool_cleanup_s {
ngx_pool_cleanup_pt handler;
void *data;
ngx_pool_cleanup_t *next;
};

typedef struct ngx_pool_large_s ngx_pool_large_t;

struct ngx_pool_large_s {
ngx_pool_large_t *next;
void *alloc;
};

typedef struct {
u_char *last;
u_char *end;
ngx_pool_t *next;
ngx_uint_t failed;
} ngx_pool_data_t;

struct ngx_pool_s {
ngx_pool_data_t d;
size_t max;
ngx_pool_t *current;
ngx_chain_t *chain;
ngx_pool_large_t *large;
ngx_pool_cleanup_t *cleanup;
ngx_log_t *log;
};

typedef struct {
ngx_fd_t fd;
u_char *name;
ngx_log_t *log;
} ngx_pool_cleanup_file_t;

void *ngx_alloc(size_t size, ngx_log_t *log);
void *ngx_calloc(size_t size, ngx_log_t *log);

ngx_pool_t *ngx_create_pool(size_t size, ngx_log_t *log);
void ngx_destroy_pool(ngx_pool_t *pool);
void ngx_reset_pool(ngx_pool_t *pool);

void *ngx_palloc(ngx_pool_t *pool, size_t size);
void *ngx_pnalloc(ngx_pool_t *pool, size_t size);
void *ngx_pcalloc(ngx_pool_t *pool, size_t size);
void *ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment);
ngx_int_t ngx_pfree(ngx_pool_t *pool, void *p);

ngx_pool_cleanup_t *ngx_pool_cleanup_add(ngx_pool_t *p, size_t size);
void ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd);
void ngx_pool_cleanup_file(void *data);
void ngx_pool_delete_file(void *data);

#endif /* NGX_PALLOC_H_INCLUDED */

ngx_uint_t ngx_pagesize;
ngx_uint_t ngx_pagesize_shift;
ngx_uint_t ngx_cacheline_size;
#define ngx_free free
#define ngx_memzero(buf, n) (void) memset(buf, 0, n)
#define ngx_memset(buf, c, n) (void) memset(buf, c, n)
#define ngx_align_ptr(p, a)
(u_char *) (((uintptr_t) § + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))
#define ngx_delete_file(name) unlink((const char *) name)
#define ngx_delete_file_n “unlink()”

void *
ngx_alloc(size_t size, ngx_log_t *log)
{
void *p;

p = malloc(size);
if (p == NULL) {printf("malloc(%lu) failed\n", size);
}printf("malloc: %p:%lu\n", p, size);return p;

}

void *
ngx_calloc(size_t size, ngx_log_t *log)
{
void *p;

p = ngx_alloc(size, log);if (p) {ngx_memzero(p, size);
}return p;

}

//#define NGX_HAVE_POSIX_MEMALIGN 1
#define NGX_HAVE_MEMALIGN 1
#if (NGX_HAVE_POSIX_MEMALIGN)

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
void *p;
int err;

err = posix_memalign(&p, alignment, size);if (err) {printf("posix_memalign(%lu, %lu) failed\n", alignment, size);p = NULL;
}printf("posix_memalign: %p:%lu @%lu\n", p, size, alignment);return p;

}

#elif (NGX_HAVE_MEMALIGN)

void *
ngx_memalign(size_t alignment, size_t size, ngx_log_t *log)
{
void *p;

p = memalign(alignment, size);
if (p == NULL) {printf("memalign(%lu, %lu) failed\n", alignment, size);
}printf("memalign: %p:%lu @%lu\n", p, size, alignment);return p;

}

#endif

//-------------------------------------------------------------------------------------------
//下面是从ngx_pcallo.c复制过来的内存池核心代码

static ngx_inline void *ngx_palloc_small(ngx_pool_t *pool, size_t size,
ngx_uint_t align);
static void *ngx_palloc_block(ngx_pool_t *pool, size_t size);
static void *ngx_palloc_large(ngx_pool_t *pool, size_t size);

ngx_pool_t *
ngx_create_pool(size_t size, ngx_log_t *log)
{
ngx_pool_t *p;

p = ngx_memalign(NGX_POOL_ALIGNMENT, size, log);
if (p == NULL) {return NULL;
}p->d.last = (u_char *) p + sizeof(ngx_pool_t);
p->d.end = (u_char *) p + size;
p->d.next = NULL;
p->d.failed = 0;size = size - sizeof(ngx_pool_t);
p->max = (size < NGX_MAX_ALLOC_FROM_POOL) ? size : NGX_MAX_ALLOC_FROM_POOL;p->current = p;
p->chain = NULL;
p->large = NULL;
p->cleanup = NULL;
p->log = log;return p;

}

void
ngx_destroy_pool(ngx_pool_t *pool)
{
ngx_pool_t *p, *n;
ngx_pool_large_t *l;
ngx_pool_cleanup_t *c;

for (c = pool->cleanup; c; c = c->next) {if (c->handler) {printf("run cleanup: %p\n", c);c->handler(c->data);}
}

#if (NGX_DEBUG)

/** we could allocate the pool->log from this pool* so we cannot use this log while free()ing the pool*/for (l = pool->large; l; l = l->next) {printf("free: %p\n", l->alloc);
}for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {printf("free: %p, unused: %lu\n", p, p->d.end - p->d.last);if (n == NULL) {break;}
}

#endif

for (l = pool->large; l; l = l->next) {if (l->alloc) {ngx_free(l->alloc);}
}for (p = pool, n = pool->d.next; /* void */; p = n, n = n->d.next) {ngx_free(p);if (n == NULL) {break;}
}

}

void
ngx_reset_pool(ngx_pool_t *pool)
{
ngx_pool_t *p;
ngx_pool_large_t *l;

for (l = pool->large; l; l = l->next) {if (l->alloc) {ngx_free(l->alloc);}
}for (p = pool; p; p = p->d.next) {p->d.last = (u_char *) p + sizeof(ngx_pool_t);p->d.failed = 0;
}pool->current = pool;
pool->chain = NULL;
pool->large = NULL;

}

void *
ngx_palloc(ngx_pool_t *pool, size_t size)
{
#if !(NGX_DEBUG_PALLOC)
if (size <= pool->max) {
return ngx_palloc_small(pool, size, 1);
}
#endif

return ngx_palloc_large(pool, size);

}

void *
ngx_pnalloc(ngx_pool_t *pool, size_t size)
{
#if !(NGX_DEBUG_PALLOC)
if (size <= pool->max) {
return ngx_palloc_small(pool, size, 0);
}
#endif

return ngx_palloc_large(pool, size);

}

static ngx_inline void *
ngx_palloc_small(ngx_pool_t *pool, size_t size, ngx_uint_t align)
{
u_char *m;
ngx_pool_t *p;

p = pool->current;do {m = p->d.last;if (align) {m = ngx_align_ptr(m, NGX_ALIGNMENT);}if ((size_t) (p->d.end - m) >= size) {p->d.last = m + size;return m;}p = p->d.next;} while (p);return ngx_palloc_block(pool, size);

}

static void *
ngx_palloc_block(ngx_pool_t *pool, size_t size)
{
u_char *m;
size_t psize;
ngx_pool_t *p, *new;

psize = (size_t) (pool->d.end - (u_char *) pool);m = ngx_memalign(NGX_POOL_ALIGNMENT, psize, pool->log);
if (m == NULL) {return NULL;
}new = (ngx_pool_t *) m;new->d.end = m + psize;
new->d.next = NULL;
new->d.failed = 0;m += sizeof(ngx_pool_data_t);
m = ngx_align_ptr(m, NGX_ALIGNMENT);
new->d.last = m + size;for (p = pool->current; p->d.next; p = p->d.next) {if (p->d.failed++ > 4) {pool->current = p->d.next;}
}p->d.next = new;return m;

}

static void *
ngx_palloc_large(ngx_pool_t *pool, size_t size)
{
void *p;
ngx_uint_t n;
ngx_pool_large_t *large;

p = ngx_alloc(size, pool->log);
if (p == NULL) {return NULL;
}n = 0;for (large = pool->large; large; large = large->next) {if (large->alloc == NULL) {large->alloc = p;return p;}if (n++ > 3) {break;}
}large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
if (large == NULL) {ngx_free(p);return NULL;
}large->alloc = p;
large->next = pool->large;
pool->large = large;return p;

}

void *
ngx_pmemalign(ngx_pool_t *pool, size_t size, size_t alignment)
{
void *p;
ngx_pool_large_t *large;

p = ngx_memalign(alignment, size, pool->log);
if (p == NULL) {return NULL;
}large = ngx_palloc_small(pool, sizeof(ngx_pool_large_t), 1);
if (large == NULL) {ngx_free(p);return NULL;
}large->alloc = p;
large->next = pool->large;
pool->large = large;return p;

}

ngx_int_t
ngx_pfree(ngx_pool_t *pool, void *p)
{
ngx_pool_large_t *l;

for (l = pool->large; l; l = l->next) {if (p == l->alloc) {printf("free: %p\n", l->alloc);ngx_free(l->alloc);l->alloc = NULL;return NGX_OK;}
}return NGX_DECLINED;

}

void *
ngx_pcalloc(ngx_pool_t *pool, size_t size)
{
void *p;

p = ngx_palloc(pool, size);
if (p) {ngx_memzero(p, size);
}return p;

}

ngx_pool_cleanup_t *
ngx_pool_cleanup_add(ngx_pool_t *p, size_t size)
{
ngx_pool_cleanup_t *c;

c = ngx_palloc(p, sizeof(ngx_pool_cleanup_t));
if (c == NULL) {return NULL;
}if (size) {c->data = ngx_palloc(p, size);if (c->data == NULL) {return NULL;}} else {c->data = NULL;
}c->handler = NULL;
c->next = p->cleanup;p->cleanup = c;printf("add cleanup: %p\n", c);return c;

}

void
ngx_pool_run_cleanup_file(ngx_pool_t *p, ngx_fd_t fd)
{
ngx_pool_cleanup_t *c;
ngx_pool_cleanup_file_t *cf;

for (c = p->cleanup; c; c = c->next) {if (c->handler == ngx_pool_cleanup_file) {cf = c->data;if (cf->fd == fd) {c->handler(cf);c->handler = NULL;return;}}
}

}

void
ngx_pool_cleanup_file(void *data)
{
ngx_pool_cleanup_file_t *c = data;

printf("file cleanup: fd:%d\n",c->fd);if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {printf(" \"%s\" failed\n", c->name);
}

}

void
ngx_pool_delete_file(void *data)
{
ngx_pool_cleanup_file_t *c = data;

ngx_err_t  err;printf("file cleanup: fd:%d %s\n",c->fd, c->name);if (ngx_delete_file(c->name) == NGX_FILE_ERROR) {err = ngx_errno;if (err != NGX_ENOENT) {printf(" \"%s\" failed\n", c->name);}
}if (ngx_close_file(c->fd) == NGX_FILE_ERROR) {printf(" \"%s\" failed\n", c->name);
}

}

#if 0

static void *
ngx_get_cached_block(size_t size)
{
void *p;
ngx_cached_block_slot_t *slot;

if (ngx_cycle->cache == NULL) {return NULL;
}slot = &ngx_cycle->cache[(size + ngx_pagesize - 1) / ngx_pagesize];slot->tries++;if (slot->number) {p = slot->block;slot->block = slot->block->next;slot->number--;return p;
}return NULL;

}

#endif
//-----------------------------------------------------------------------------------------
//array
typedef struct {
size_t len;
u_char *data;
} ngx_str_t;

#define ngx_memcpy(dst, src, n) (void) memcpy(dst, src, n)

#ifndef NGX_ARRAY_H_INCLUDED
#define NGX_ARRAY_H_INCLUDED

typedef struct {
void *elts;
ngx_uint_t nelts;
size_t size;
ngx_uint_t nalloc;
ngx_pool_t *pool;
} ngx_array_t;

ngx_array_t *ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size);
void ngx_array_destroy(ngx_array_t *a);
void *ngx_array_push(ngx_array_t *a);
void *ngx_array_push_n(ngx_array_t *a, ngx_uint_t n);

static ngx_inline ngx_int_t
ngx_array_init(ngx_array_t *array, ngx_pool_t pool, ngx_uint_t n, size_t size)
{
/

* set “array->nelts” before “array->elts”, otherwise MSVC thinks
* that “array->nelts” may be used without having been initialized
*/

array->nelts = 0;
array->size = size;
array->nalloc = n;
array->pool = pool;array->elts = ngx_palloc(pool, n * size);
if (array->elts == NULL) {return NGX_ERROR;
}return NGX_OK;

}

#endif /* NGX_ARRAY_H_INCLUDED */

ngx_array_t *
ngx_array_create(ngx_pool_t *p, ngx_uint_t n, size_t size)
{
ngx_array_t *a;

a = ngx_palloc(p, sizeof(ngx_array_t));
if (a == NULL) {return NULL;
}if (ngx_array_init(a, p, n, size) != NGX_OK) {return NULL;
}return a;

}

void
ngx_array_destroy(ngx_array_t *a)
{
ngx_pool_t *p;

p = a->pool;if ((u_char *) a->elts + a->size * a->nalloc == p->d.last) {p->d.last -= a->size * a->nalloc;
}if ((u_char *) a + sizeof(ngx_array_t) == p->d.last) {p->d.last = (u_char *) a;
}

}

void *
ngx_array_push(ngx_array_t *a)
{
void *elt, *new;
size_t size;
ngx_pool_t *p;

if (a->nelts == a->nalloc) {/* the array is full */size = a->size * a->nalloc;p = a->pool;if ((u_char *) a->elts + size == p->d.last&& p->d.last + a->size <= p->d.end){/** the array allocation is the last in the pool* and there is space for new allocation*/p->d.last += a->size;a->nalloc++;} else {/* allocate a new array */new = ngx_palloc(p, 2 * size);if (new == NULL) {return NULL;}ngx_memcpy(new, a->elts, size);a->elts = new;a->nalloc *= 2;}
}elt = (u_char *) a->elts + a->size * a->nelts;
a->nelts++;return elt;

}

void *
ngx_array_push_n(ngx_array_t *a, ngx_uint_t n)
{
void *elt, *new;
size_t size;
ngx_uint_t nalloc;
ngx_pool_t *p;

size = n * a->size;if (a->nelts + n > a->nalloc) {/* the array is full */p = a->pool;if ((u_char *) a->elts + a->size * a->nalloc == p->d.last&& p->d.last + size <= p->d.end){/** the array allocation is the last in the pool* and there is space for new allocation*/p->d.last += size;a->nalloc += n;} else {/* allocate a new array */nalloc = 2 * ((n >= a->nalloc) ? n : a->nalloc);new = ngx_palloc(p, nalloc * a->size);if (new == NULL) {return NULL;}ngx_memcpy(new, a->elts, a->nelts * a->size);a->elts = new;a->nalloc = nalloc;}
}elt = (u_char *) a->elts + a->size * a->nelts;
a->nelts += n;return elt;

}

//-------------------------------------------------------------------------------------------
//下面是Main函数和内存池打印代码

void print_pool(ngx_pool_t *pool)

{

if (pool->large != NULL){printf("has large memory\n");for(ngx_pool_large_t* i = pool->large; i!=NULL; i = i->next){printf("\t\tlarge next=0x%x\n", i->next);printf("\t\tlarge alloc=0x%x\n", i->alloc);}}int i=1;while(pool){printf("pool=0x%x,index:%d\n", pool, i++);printf("\t\tlast=0x%x\n", (pool->d).last);printf("\t\tend=0x%x\n",(pool->d).end);printf("\t\tnext=0x%x\n",(pool->d).next);printf("\t\tfailed=%d\n",pool->d.failed);printf("\t\tmax=%d\n",pool->max);printf("\t\tcurrent=0x%x\n",pool->current);printf("\t\tchain=0x%x\n",pool->chain);printf("\t\tlarge=0x%x\n",pool->large);printf("\t\tcleanup=0x%x\n",pool->cleanup);printf("\t\tlog=0x%x\n",pool->log);printf("\t\tavailable pool memory=%d\n", pool->d.end-pool->d.last);printf("\n");pool=pool->d.next;}}

void print_array(int *a,int size)

{

for(int i=0; i<size; i++){printf("%d,",a[i]);}printf("\n");

}

int main()

{

ngx_pool_t *pool;int array_size = 1;int array_size_large = 1024;int page_size = getpagesize();//获得一页的大小printf("page_size:%d\n", page_size);printf("----------------------------\n");printf("create a new pool\n");pool = ngx_create_pool(1024, NULL);//创建一个大小为1024的内存池print_pool(pool);printf("----------------------------\n");printf("alloc block 1 from the pool:\n");int *a1 = ngx_palloc(pool, sizeof(int) * array_size);//分配第一块内存 用于创建数组for (int i=0; i< array_size; i++){a1[i] = i+1;}print_pool(pool);printf("----------------------------\n");printf("alloc block 2 from the pool:\n");int *a2 = ngx_palloc(pool, sizeof(int) * array_size);//分配第二块内存 用于创建数组,这个时候会创建第二个内存池节点for (int i=0; i< array_size; i++){a2[i] = 12345678;}print_pool(pool);printf("----------------------------\n");printf("alloc large memory:\n");printf("\t\tlarge next before=0x%x\n", pool->current->d.last);int * a3 = ngx_palloc(pool, sizeof(int) * array_size_large);//由于大小超过了max的值 ngx_palloc中会调用ngx_palloc_large分配大块内存printf("\t\tlarge next after=0x%x\n", pool->large);for (int i=0; i< array_size_large; i++){a3[i] = i+1;}print_array(a1,array_size);//分配的第一块内存块首地址print_array(a2,array_size);//分配的第二块内存块首地址

// print_array(a3,array_size_large);//分配的大内存块首地址

//在内存数组中分三次写入 “hello”, “world”, “!”,然后使用指针加偏移,地址加数据长度两种方式将保存在数组中的文字打印出来
// char mychar[6] = “hello”;
// ngx_str_t mydata = {sizeof(mychar),mychar};
ngx_array_t *a = NULL;
a = ngx_array_create(pool, 1, sizeof(ngx_str_t));

ngx_str_t *s = ngx_array_push(a);
s->data = "hello";
s->len = sizeof(s->data);
printf("a->nelts: %ld, a->nalloc:%ld\n",a->nelts,a->nalloc);
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts))->data);
printf("ngx_array_push:%s\n",s->data);ngx_str_t *s1 = ngx_array_push(a);
s1->data = "wrold";
s1->len = sizeof(s1->data);
printf("a->nelts: %ld, a->nalloc:%ld\n",a->nelts,a->nalloc);
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts+sizeof(ngx_str_t)))->data);//地址加数据长度
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts)+1)->data); //使用指针加偏移
printf("ngx_array_push:%s\n",s1->data);ngx_str_t *s2 = ngx_array_push(a);
s2->data = "!";
s2->len = sizeof(s2->data);
printf("a->nelts: %ld, a->nalloc:%ld\n",a->nelts,a->nalloc);
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts+sizeof(ngx_str_t)*(a->nelts-1)))->data);//地址加数据长度
printf("ngx_array_push:%s\n",((ngx_str_t *)(a->elts)+a->nelts-1)->data); //使用指针加偏移
printf("ngx_array_push:%s\n",s2->data);print_pool(pool);ngx_destroy_pool(pool);return 0;

}

相关文章:

将Nginx源码数组结构(ngx_array.c)和内存池代码单独编译运行,附代码

在上面一篇的基础上把Nginx源码数组结构也摘录下来&#xff0c;也增加了测试代码&#xff0c;编译运行。 https://blog.csdn.net/katerdaisy/article/details/132358883 《将nginx内存池代码单独编译运行&#xff0c;了解nginx内存池工作原理&#xff0c;附代码》 核心代码&…...

java forEach中不能使用break和continue的原因

1.首先了解break和continue的使用范围和作用 1.1使用范围 break适用范围&#xff1a;只能用于switch或者是循环语句中。当然可以用于增强for循环。 continue适用范围: 用于循环语句中。 1.2作用 break: 1. break用于switch语句的作用是结束一个switch语句。 2. break用于循…...

[杂项]水浒英雄谱系列电影列表

年份 片名 导演 主演 2006-01-01 母夜叉孙二娘 张建亚 周海媚 、 莫少聪 、 于承惠 [1] 2008-01-01 碧瑶霜迷案 黄祖权 陈龙 、 陈德容 、 翁家明 [7] 2008-05-09 青面兽杨志 张建亚 吕良伟 、 计春华 、 孟广美 [2] 2008-05-09 扈三娘与矮脚虎王英 张建亚 曾宝仪 、 郭德纲 、…...

6.RocketMQ之索引文件ConsumeQueue

本文着重分析为consumequeue/topic/queueId目录下的索引文件。 1.ConsumeQueueStore public class ConsumeQueueStore {protected final ConcurrentMap<String>, ConcurrentMap<Integer>, ConsumeQueueInterface>> consumeQueueTable;public boolean load(…...

【C++学习手札】一文带你认识C++虚继承​​

食用指南&#xff1a;本文在有C基础的情况下食用更佳 &#x1f340;本文前置知识&#xff1a;C虚函数&#xff08;很重要&#xff0c;内部剖析&#xff09; ♈️今日夜电波&#xff1a;僕らのつづき—柊優花 1:06 ━━━━━━️&#x1f49f;──────── 3:51 …...

神经网络基础-神经网络补充概念-63-残差网络

概念 残差网络&#xff08;Residual Network&#xff0c;ResNet&#xff09;是一种深度卷积神经网络结构&#xff0c;旨在解决深层网络训练中的梯度消失和梯度爆炸问题&#xff0c;以及帮助训练非常深的网络。ResNet 在2015年被提出&#xff0c;其核心思想是引入了"残差块…...

【从0开始学架构笔记】01 基础架构

文章目录 一、架构的定义1. 系统与子系统2. 模块与组件3. 框架与架构4. 重新定义架构 二、架构设计的目的三、复杂度来源&#xff1a;高性能1. 单机复杂度2. 集群复杂度2.1 任务分配2.2 任务分解&#xff08;微服务&#xff09; 四、复杂度来源&#xff1a;高可用1. 计算高可用…...

vue3+ts+vite使用el-breadcrumb实现面包屑组件,实现面包屑过渡动画

简介 使用 element-plus 的 el-breadcrumb 组件&#xff0c;实现根据页面路由动态生成面包屑导航&#xff0c;并实现面包屑导航的切换过渡动画 一、先看效果加粗样式 1.1 静态效果 1.2 动态效果 二、全量代码 <script lang"ts" setup> import { ref, watch…...

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)四(116)

需求&#xff1a;&#xff1a;前端根据后端的返回数据&#xff1a;画统计图&#xff1b; 1.动态获取地域数据以及数据中的平均值&#xff0c;按照平均值降序排序&#xff1b; 说明&#xff1a; X轴是动态的&#xff0c;有对应区域数据则展示&#xff1b; X轴 区域数据降序排序…...

Chrome命令行开关

Electron 支持的命令行开关 –client-certificatepath 设置客户端的证书文件 path . –ignore-connections-limitdomains 忽略用 , 分隔的 domains 列表的连接限制. –disable-http-cache 禁止请求 HTTP 时使用磁盘缓存. –remote-debugging-portport 在指定的 端口 通…...

元宇宙赛道加速破圈 和数软件抓住“元宇宙游戏”发展新风口

当下海外游戏市场仍然具备较大的增长空间。据机构预测&#xff0c;至2025年全球移动游戏市场规模将达1606亿美元&#xff0c;对应2020-2025年复合增长率11&#xff05;。与此同时&#xff0c;随着元宇宙概念持续升温&#xff0c;国内外多家互联网巨头纷纷入场。行业分析平台New…...

Vue的鼠标键盘事件

Vue的鼠标键盘事件 原生 鼠标事件(将v-on简写为) click // 点击 dblclick // 双击 mousedown // 按下 mousemove // 移动 mouseleave // 离开 mouseout // 移出 mouseenter // 进入 mouseover // 鼠标悬浮mousedown.left 键盘事件 keydown //键盘按下时触发 keypress …...

Bytebase 2.6.0 - ​支持通过 LDAP 配置 SSO,支持 RisingWave 数据库

&#x1f680; 新功能 支持通过 LDAP 配置 SSO。支持增加多个只读连接。Schema 模版支持列类型约束。支持 RisingWave 数据库。库表同步功能支持 TiDB。数据脱敏功能支持 SQL Server。SQL 审核 CI 功能支持 Azure DevOps。 &#x1f384; 改进 支持设置数据库的环境与所属实…...

C# 读取pcd、ply点云文件数据

最近研究了下用pcl读取点云数据&#xff0c;又做了个C#的dll&#xff0c;方便读取&#xff0c;同样这个dll基于pcl 最新版本1.13.1版本开发。 上次做的需要先得到点云长度&#xff0c;再获取数据。这次这个定义了一个PointCloudXYZ类来存数据。将下面的dll拷贝到可执行目录下&a…...

LeetCode1387 将整数按权重排序

思路 首先是这种计算权重的方式很有可能出现重复&#xff0c;所以需要记忆化搜索记忆化搜索&#xff1a;先查表再计算&#xff0c;先存表再返回。将整数 x 和计算的权重分别存储数组的0和1的位置重写compare将数组排序按规则排序返回结果 代码 class Solution {private Hash…...

正则表达式--Intellij IDEA常用的替换

原文网址&#xff1a;正则表达式--Intellij IDEA常用的替换_IT利刃出鞘的博客-CSDN博客 简介 本文介绍IDEA使用正则表达式进行替换时的常用的一些示例。 根据注释加注解 需求 将 /*** abc*/ 改为&#xff1a; /*** abc*/ ApiModelOperation("abc") 方法 选…...

前端如何安全的渲染HTML字符串?

在现代的Web 应用中&#xff0c;动态生成和渲染 HTML 字符串是很常见的需求。然而&#xff0c;不正确地渲染HTML字符串可能会导致安全漏洞&#xff0c;例如跨站脚本攻击&#xff08;XSS&#xff09;。为了确保应用的安全性&#xff0c;我们需要采取一些措施来在安全的环境下渲染…...

C++学习第十四天----for循环

1.递增/递减运算符和指针 将*和同时用于指针的优先级&#xff1f; 答&#xff1a;前缀递增&#xff0c;前缀递减和解除引用运算符的优先级相同&#xff0c;以从右到左的方式进行结合&#xff1b;后缀递增和后缀递减的优先级相同&#xff0c;但比前缀运算符的优先级高&#xff0…...

快速解决在进入浏览器时,明明连接了网络,但是显示你尚未连接,代理服务器可能有问题。

在进入浏览器时&#xff0c;明明连接了网络&#xff0c;但是显示你尚未连接&#xff0c;代理服务器可能有问题&#xff0c;如下图。 一般情况下&#xff0c;可能是因为你使用了某些VPN&#xff0c;然后VPN使用时修改了你的网络设置&#xff0c;我们可以通过以下方法快速解决。 …...

TypeScript入门指南

TypeScript学习总结内容目录&#xff1a; TypeScript概述 TypeScript特性。Javascript与TypeScript的区别 * TypeScript安装及其环境搭建TypeScript类型声明 * 单个类型声明&#xff0c;多个类型声明 * 任意类型声明 * 函数类型声明 * unknown类型…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

[Java恶补day16] 238.除自身以外数组的乘积

给你一个整数数组 nums&#xff0c;返回 数组 answer &#xff0c;其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法&#xff0c;且在 O(n) 时间复杂度…...

Spring数据访问模块设计

前面我们已经完成了IoC和web模块的设计&#xff0c;聪明的码友立马就知道了&#xff0c;该到数据访问模块了&#xff0c;要不就这俩玩个6啊&#xff0c;查库势在必行&#xff0c;至此&#xff0c;它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据&#xff08;数据库、No…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

Elastic 获得 AWS 教育 ISV 合作伙伴资质,进一步增强教育解决方案产品组合

作者&#xff1a;来自 Elastic Udayasimha Theepireddy (Uday), Brian Bergholm, Marianna Jonsdottir 通过搜索 AI 和云创新推动教育领域的数字化转型。 我们非常高兴地宣布&#xff0c;Elastic 已获得 AWS 教育 ISV 合作伙伴资质。这一重要认证表明&#xff0c;Elastic 作为 …...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...