将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类型…...

大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...

【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...

python执行测试用例,allure报乱码且未成功生成报告
allure执行测试用例时显示乱码:‘allure’ �����ڲ����ⲿ���Ҳ���ǿ�&am…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...

Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
es6+和css3新增的特性有哪些
一:ECMAScript 新特性(ES6) ES6 (2015) - 革命性更新 1,记住的方法,从一个方法里面用到了哪些技术 1,let /const块级作用域声明2,**默认参数**:函数参数可以设置默认值。3&#x…...

【iOS】 Block再学习
iOS Block再学习 文章目录 iOS Block再学习前言Block的三种类型__ NSGlobalBlock____ NSMallocBlock____ NSStackBlock__小结 Block底层分析Block的结构捕获自由变量捕获全局(静态)变量捕获静态变量__block修饰符forwarding指针 Block的copy时机block作为函数返回值将block赋给…...

Canal环境搭建并实现和ES数据同步
作者:田超凡 日期:2025年6月7日 Canal安装,启动端口11111、8082: 安装canal-deployer服务端: https://github.com/alibaba/canal/releases/1.1.7/canal.deployer-1.1.7.tar.gz cd /opt/homebrew/etc mkdir canal…...