我将尝试用一个例子来解释:
假设我想创建一个固定数字的消息列表,3。
from shapely.affinity import scale
from shapely.ops import transform
from shapely.geometry import Polygon
def reflection(x0):
return lambda x, y: (2*x0 - x, y)
P = Polygon([[0, 0], [1, 1], [1, 2], [0, 1]])
print(P)
#POLYGON ((0 0, 1 1, 1 2, 0 1, 0 0))
Q1 = scale(P, xfact = -1, origin = (1, 0))
Q2 = transform(reflection(1), P)
print(Q1)
#POLYGON ((2 0, 1 1, 1 2, 2 1, 2 0))
print(Q2)
#POLYGON ((2 0, 1 1, 1 2, 2 1, 2 0))
此列表中的每条消息都应以固定大小存储(例如16个字符,因此每条消息在内存中保存16个字节,总共48个字节)。
char* p_msglist[3];
在将这些消息指向列表后,我打印了char msg[16] = "first message";
char msg2[16] = "second message";
char msg3[16] = "third message";
第一条消息和列表:
sizeof
输出:
p_msglist[0] = msg;
p_msglist[1] = msg2;
p_msglist[2] = msg3;
printf("%lu\n", sizeof(msg));
printf("%lu\n", sizeof(p_msglist));
我知道 char指针包含8个字节,我们的消息列表初始化为3个元素,最后一行打印出24个。我想问:
有没有办法让我的列表保存16 //size of msg is ok.
24
个字节。试着问:我可以确定我的列表在内存中保存了48个字节吗?
如果我想分配内存(3*16=48
等),我应该关心列表的指针和列表本身(24字节+48字节)吗?
提前致谢。
答案 0 :(得分:2)
第一个问题的答案是否定的。你无法从指针本身获得大小。
这取决于: -
如果您想分配那些char*
,那么您需要考虑。
如果您确定只需3 char*
,那么no
就不用考虑了。
但在这两种情况下都需要分配内存来存储字符串。例如,您将在此处分配用于存储16个字符的空间。
(或简单地将其分配给某些字符串文字)。
答案 1 :(得分:1)
你对一个指针数组的工作原理有一个非常基本的误解。它将指针保存到内存中,而不是内存本身。 (它不能这样做,因为在您声明p_msglist
时,消息的大小尚不清楚。)
char* p_msglist[3];
这是一个由三个指针组成的数组。这些指针中的每一个都表示一个地址。地址通常是(但不是在每个硬件上)32或64位大;分别为4或8个字节。
你正在使用64位机器,因此你的三个指针数组是3 x 8 = 24个字节。
现在重点:
三个指针中的每一个都可以指向一些不同的地址。你的三条消息在内存中甚至彼此靠近,既没有必要也没有保证。指向的消息的内存在sizeof p_msglist
中包含不 - 也不应该包含在内。
如果您希望malloc
整个p_msglist
和的内存p_msglist
,您必须:
p_msglist
分配24个字节;然后free()
的元素中。再次释放内存时,您必须在每封邮件上调用free( p_msglist[0] )
(即free( p_msglist[1] )
,free( p_msglist[2] )
,free( p_msglist )
),和 msg_mem
本身。 (重要提示:首先释放消息,然后然后释放数组。相反的方法是未定义行为。)
如果要确保消息在内存中是连续的,则需要为消息分配3 * 16 = 48个字节(假设您将其存储在msg_mem
中),并存储{{1}在p_msglist[0]
中,将msg_mem + 16
存储在p_msglist[1]
中,并将msg_mem + 32
存储在p_msglist[2]
中。
释放 时,不得仅针对free()
(和p_msglist[0]
上的p_msglist
点击free()
。如果你动态分配了内存)。您只能在之前从其中一个分配函数获得的地址上调用p_msglist
。
如果要在连续且已分配的内存中包含消息和 sizeof( p_msglist ) + sizeof( msg ) + sizeof( msg2 ) + sizeof( msg3 )
,则必须分配48 + 24 = 72字节的内存(free( p_msglist )
)。 ..然后仅 malloc
之后。
如果您不想char p_msglist[3][16] = { { "first message" }, { "second message" }, { "third message" } };
内存 并且仍希望内存位于一个块中,您可以声明...
free()
这将分配一个3 x 16个字符的二维数组,按指示初始化它们。但是,这当然只是一个本地对象,它会像任何其他局部变量一样超出范围(与动态分配的内存相反,在p_msglist
d之前保持有效)
关于后一种结构的“有趣”的事情是,因为sizeof p_msglist
是一个“直接”的二维数组,而不是指向个别数组的三个指针, /home/badr/.rbenv/versions/2.4.1/lib/ruby/2.4.0/pathname.rb:520:in `relative_path_from'
devise (4.3.0) lib/devise/failure_app.rb:58:in `recall'
devise (4.3.0) lib/devise/failure_app.rb:39:in `respond'
actionpack (5.1.4) lib/abstract_controller/base.rb:186:in `process_action'
actionpack (5.1.4) lib/abstract_controller/base.rb:124:in `process'
actionpack (5.1.4) lib/action_controller/metal.rb:189:in `dispatch'
actionpack (5.1.4) lib/action_controller/metal.rb:242:in `block in action'
devise (4.3.0) lib/devise/failure_app.rb:21:in `call'
devise (4.3.0) lib/devise/delegator.rb:5:in `call'
warden (1.2.7) lib/warden/manager.rb:143:in `call_failure_app'
warden (1.2.7) lib/warden/manager.rb:129:in `process_unauthenticated'
warden (1.2.7) lib/warden/manager.rb:44:in `call'
rack (2.0.3) lib/rack/etag.rb:25:in `call'
rack (2.0.3) lib/rack/conditional_get.rb:38:in `call'
rack (2.0.3) lib/rack/head.rb:12:in `call'
rack (2.0.3) lib/rack/session/abstract/id.rb:232:in `context'
rack (2.0.3) lib/rack/session/abstract/id.rb:226:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/cookies.rb:613:in `call'
activerecord (5.1.4) lib/active_record/migration.rb:556:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:26:in `block in call'
activesupport (5.1.4) lib/active_support/callbacks.rb:97:in `run_callbacks'
actionpack (5.1.4) lib/action_dispatch/middleware/callbacks.rb:24:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/debug_exceptions.rb:59:in `call'
web-console (3.5.1) lib/web_console/middleware.rb:135:in `call_app'
web-console (3.5.1) lib/web_console/middleware.rb:28:in `block in call'
web-console (3.5.1) lib/web_console/middleware.rb:18:in `catch'
web-console (3.5.1) lib/web_console/middleware.rb:18:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/show_exceptions.rb:31:in `call'
railties (5.1.4) lib/rails/rack/logger.rb:36:in `call_app'
railties (5.1.4) lib/rails/rack/logger.rb:24:in `block in call'
activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `block in tagged'
activesupport (5.1.4) lib/active_support/tagged_logging.rb:26:in `tagged'
activesupport (5.1.4) lib/active_support/tagged_logging.rb:69:in `tagged'
railties (5.1.4) lib/rails/rack/logger.rb:24:in `call'
sprockets-rails (3.2.1) lib/sprockets/rails/quiet_assets.rb:13:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/remote_ip.rb:79:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/request_id.rb:25:in `call'
rack (2.0.3) lib/rack/method_override.rb:22:in `call'
rack (2.0.3) lib/rack/runtime.rb:22:in `call'
activesupport (5.1.4) lib/active_support/cache/strategy/local_cache_middleware.rb:27:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/executor.rb:12:in `call'
actionpack (5.1.4) lib/action_dispatch/middleware/static.rb:125:in `call'
rack (2.0.3) lib/rack/sendfile.rb:111:in `call'
railties (5.1.4) lib/rails/engine.rb:522:in `call'
puma (3.10.0) lib/puma/configuration.rb:225:in `call'
puma (3.10.0) lib/puma/server.rb:605:in `handle_request'
puma (3.10.0) lib/puma/server.rb:437:in `process_client'
puma (3.10.0) lib/puma/server.rb:301:in `block in run'
puma (3.10.0) lib/puma/thread_pool.rb:120:in `block in spawn_thread'
在这种情况下,实际上是3 x 16 = 48 ...