如何获取字符串数组的内存大小?

时间:2017-11-09 15:39:02

标签: c arrays memory

我将尝试用一个例子来解释:

假设我想创建一个固定数字的消息列表,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字节)吗?

提前致谢。

2 个答案:

答案 0 :(得分:2)

第一个问题的答案是否定的。你无法从指针本身获得大小。

这取决于: -

  1. 如果您想分配那些char*,那么您需要考虑。

  2. 如果您确定只需3 char*,那么no就不用考虑了。

  3. 但在这两种情况下都需要分配内存来存储字符串。例如,您将在此处分配用于存储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个字节;然后
  • 为每条消息分配16个字节,分别为,并将该消息的地址分别存储在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 ...