将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源码数组结构也摘录下来,也增加了测试代码,编译运行。 https://blog.csdn.net/katerdaisy/article/details/132358883 《将nginx内存池代码单独编译运行,了解nginx内存池工作原理,附代码》 核心代码&…...

java forEach中不能使用break和continue的原因
1.首先了解break和continue的使用范围和作用 1.1使用范围 break适用范围:只能用于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++虚继承
食用指南:本文在有C基础的情况下食用更佳 🍀本文前置知识:C虚函数(很重要,内部剖析) ♈️今日夜电波:僕らのつづき—柊優花 1:06 ━━━━━━️💟──────── 3:51 …...
神经网络基础-神经网络补充概念-63-残差网络
概念 残差网络(Residual Network,ResNet)是一种深度卷积神经网络结构,旨在解决深层网络训练中的梯度消失和梯度爆炸问题,以及帮助训练非常深的网络。ResNet 在2015年被提出,其核心思想是引入了"残差块…...

【从0开始学架构笔记】01 基础架构
文章目录 一、架构的定义1. 系统与子系统2. 模块与组件3. 框架与架构4. 重新定义架构 二、架构设计的目的三、复杂度来源:高性能1. 单机复杂度2. 集群复杂度2.1 任务分配2.2 任务分解(微服务) 四、复杂度来源:高可用1. 计算高可用…...

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

【Java 动态数据统计图】动态数据统计思路案例(动态,排序,数组)四(116)
需求::前端根据后端的返回数据:画统计图; 1.动态获取地域数据以及数据中的平均值,按照平均值降序排序; 说明: X轴是动态的,有对应区域数据则展示; X轴 区域数据降序排序…...
Chrome命令行开关
Electron 支持的命令行开关 –client-certificatepath 设置客户端的证书文件 path . –ignore-connections-limitdomains 忽略用 , 分隔的 domains 列表的连接限制. –disable-http-cache 禁止请求 HTTP 时使用磁盘缓存. –remote-debugging-portport 在指定的 端口 通…...

元宇宙赛道加速破圈 和数软件抓住“元宇宙游戏”发展新风口
当下海外游戏市场仍然具备较大的增长空间。据机构预测,至2025年全球移动游戏市场规模将达1606亿美元,对应2020-2025年复合增长率11%。与此同时,随着元宇宙概念持续升温,国内外多家互联网巨头纷纷入场。行业分析平台New…...

Vue的鼠标键盘事件
Vue的鼠标键盘事件 原生 鼠标事件(将v-on简写为) click // 点击 dblclick // 双击 mousedown // 按下 mousemove // 移动 mouseleave // 离开 mouseout // 移出 mouseenter // 进入 mouseover // 鼠标悬浮mousedown.left 键盘事件 keydown //键盘按下时触发 keypress …...
Bytebase 2.6.0 - 支持通过 LDAP 配置 SSO,支持 RisingWave 数据库
🚀 新功能 支持通过 LDAP 配置 SSO。支持增加多个只读连接。Schema 模版支持列类型约束。支持 RisingWave 数据库。库表同步功能支持 TiDB。数据脱敏功能支持 SQL Server。SQL 审核 CI 功能支持 Azure DevOps。 🎄 改进 支持设置数据库的环境与所属实…...

C# 读取pcd、ply点云文件数据
最近研究了下用pcl读取点云数据,又做了个C#的dll,方便读取,同样这个dll基于pcl 最新版本1.13.1版本开发。 上次做的需要先得到点云长度,再获取数据。这次这个定义了一个PointCloudXYZ类来存数据。将下面的dll拷贝到可执行目录下&a…...
LeetCode1387 将整数按权重排序
思路 首先是这种计算权重的方式很有可能出现重复,所以需要记忆化搜索记忆化搜索:先查表再计算,先存表再返回。将整数 x 和计算的权重分别存储数组的0和1的位置重写compare将数组排序按规则排序返回结果 代码 class Solution {private Hash…...
正则表达式--Intellij IDEA常用的替换
原文网址:正则表达式--Intellij IDEA常用的替换_IT利刃出鞘的博客-CSDN博客 简介 本文介绍IDEA使用正则表达式进行替换时的常用的一些示例。 根据注释加注解 需求 将 /*** abc*/ 改为: /*** abc*/ ApiModelOperation("abc") 方法 选…...

前端如何安全的渲染HTML字符串?
在现代的Web 应用中,动态生成和渲染 HTML 字符串是很常见的需求。然而,不正确地渲染HTML字符串可能会导致安全漏洞,例如跨站脚本攻击(XSS)。为了确保应用的安全性,我们需要采取一些措施来在安全的环境下渲染…...
C++学习第十四天----for循环
1.递增/递减运算符和指针 将*和同时用于指针的优先级? 答:前缀递增,前缀递减和解除引用运算符的优先级相同,以从右到左的方式进行结合;后缀递增和后缀递减的优先级相同,但比前缀运算符的优先级高࿰…...

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

TypeScript入门指南
TypeScript学习总结内容目录: TypeScript概述 TypeScript特性。Javascript与TypeScript的区别 * TypeScript安装及其环境搭建TypeScript类型声明 * 单个类型声明,多个类型声明 * 任意类型声明 * 函数类型声明 * unknown类型…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...

MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

Map相关知识
数据结构 二叉树 二叉树,顾名思义,每个节点最多有两个“叉”,也就是两个子节点,分别是左子 节点和右子节点。不过,二叉树并不要求每个节点都有两个子节点,有的节点只 有左子节点,有的节点只有…...

技术栈RabbitMq的介绍和使用
目录 1. 什么是消息队列?2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...

R 语言科研绘图第 55 期 --- 网络图-聚类
在发表科研论文的过程中,科研绘图是必不可少的,一张好看的图形会是文章很大的加分项。 为了便于使用,本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中,获取方式: R 语言科研绘图模板 --- sciRplothttps://mp.…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

stm32wle5 lpuart DMA数据不接收
配置波特率9600时,需要使用外部低速晶振...