为什么将数组二进制保存在文件中有效? [C++]

发布于 2024-10-16 02:01:11 字数 428 浏览 1 评论 0原文

这里是 C++ 新手。

我试图找出以下将缓冲区写入文件的行:

fOut.write((char *)&_data, sizeof(_data));

_data = 整数数组...

我有几个问题:

  1. &_data 是第一个元素的地址数组的?
  2. 无论它是什么地址,是否意味着我们只保存数组的地址?那么为什么我释放数组后仍然可以访问该数组呢?
  3. 我不应该传递 sizeof(_data)*arrLength 吗?传递 int 的大小(在本例中)而不是整个数组的大小有何意义?
  4. 处理地址时,转换为 char* 意味着什么?

我真的很感激一些澄清。

C++ newbie here.

I'm trying to figure out the following line that writes a buffer into a file:

fOut.write((char *)&_data, sizeof(_data));

_data = array of integers...

I have a couple of questions:

  1. Is &_data the address to the first element of the array?
  2. Whatever address it is, does that mean that we only save the address of the array? then how come I still can access the array after I free it?
  3. Shouldn't I pass sizeof(_data)*arrLength? what is the meaning of passing the size of int (in this case) and not the size of the entire array?
  4. What does casting into char* mean when dealing with addresses?

I would really appreciate some clarifications.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

奢欲 2024-10-23 02:01:11

与您的评论相反,数组必须是自动或静态存储持续时间才能使 sizeof 工作。

  1. 它应该只是(char*)_data。数组的名称隐式转换为指向第一个元素的指针。

  2. 不,write 需要一个指针,并存储在该位置找到的内容,而不是该位置的地址。

  3. 没有。由于 _data 是一个数组,因此 sizeof (_data) 是数组中所有元素的累积大小。如果 _data 是一个指针(例如当在堆上动态分配数组时),您可能需要 numElems * sizeof(_data[0])。将指针的大小乘以元素的数量没有任何帮助。

  4. 这意味着该地址的内容将被视为一系列单独的字节,失去它可能具有的任何数字含义。这样做通常是为了执行高效的数据批量复制,无论是到文件还是从文件复制,或者使用memcpy/memmove。数据类型应该是 POD(普通旧数据),否则您将得到意外结果。

如果 _data 是一个指向从堆分配的数组的指针,正如您的评论所暗示的那样,那么代码就被严重破坏了。在这种情况下,您只保存地址,如果您将文件加载回程序的同一实例,它可能看起来可以工作,但这只是因为它发现数据仍在内存中的同一地址处。数据实际上并不在文件中,如果您在加载文件之前重新启动程序,您会发现数据消失了。进行我在 (1) 和 (3) 中提到的更改,以便保存完整的数组,无论它是自动分配、静态分配还是动态分配。

Contrary to your comment, the array must be automatic or static storage duration in order for sizeof to work.

  1. It should be just (char*)_data. The name of an array implicitly converts to a pointer to the first element.

  2. No, write expects a pointer, and stores the content found at that location, not the location's address.

  3. No. Since _data is an array, sizeof (_data) is the cumulative size of all elements in the array. If _data were a pointer (such as when an array is dynamically allocated on the heap), you would want numElems * sizeof(_data[0]). Multiplying the size of a pointer by the number of elements isn't helpful.

  4. It means that the content at that address will be treated as a series of individual bytes, losing whatever numeric meaning it might have had. This is often done to perform efficient bulk copy of data, either to and from a file, or with memcpy/memmove. The data type should be POD (plain old data) or you'll get unexpected results.

If _data is a pointer to an array allocated from the heap, as your comment suggests, then the code is badly broken. In that case, you are saving just the address, and it may appear to work if you load the file back into the same instance of your program, but that's just because it's finding the data still in memory at the same address. The data wouldn't actually be in the file, and if you re-started the program before loading the file, you'd find that the data was gone. Make the changes I mentioned in both (1) and (3) in order to save the complete array regardless of whether it's allocated automatic, static, or dynamically.

楠木可依 2024-10-23 02:01:11

强制转换为 char* 意味着什么
处理地址时?

想象一下这个简单的例子

int x = 12;
char * z = (char *)&x;

,并假设一个 int 长度为 4 个字节的架构。来自 C++ 标准 sizeof(char)==1

在表达式 char * zchar * 部分,您可以说它被用于

我给出的示例的第二行的指针算术,发生的情况是 < code>z 现在指向 x 所具有的第一个(4 个字节)。执行 ++z; 将使 z 指向(在我的示例中)4byte int 的第二个字节

。声明的一部分用于指针算术,以简化事情。 ++(char *) 会将您移动一个字节,而 ++(int *) 会将您移动相应的字节数 int< /code> 占用内存。

What does casting into char* means
when dealing with addresses?

Imagine this simple example

int x = 12;
char * z = (char *)&x;

And assume an architecture where int is 4 bytes long. From the C++ Standard sizeof(char)==1.

On the expression char * z the char * part, you could say that is being used for pointer arithmetic

on the Second line of the example I gave, what happens is that z now points to the first (out of 4 bytes) that x has. Doing a ++z; will make z point to the Second Byte of the (in my example) 4byte int

You could say that the left part of a declaration is used for pointer arithmetic, to simplify things. a ++(char *) would move you by one byte, while a ++(int *) would move you by the corresponding number of bytes int occupies on the memory.

不喜欢何必死缠烂打 2024-10-23 02:01:11
  1. 否,write 使用这个地址作为首位置,通过 sizeof(_data) 读取 写入整个数组
  2. sizeof(_data) 会返回整个数组的大小 与 sizeof(int)
  3. 表示读取的数据是 byte按字节,这是 write 所需的指针,因为它以二进制格式写入(逐字节)
  1. Yes
  2. No, write uses this address as the first location, and reads through sizeof(_data) writing the whole array
  3. sizeof(_data) will return the size of the entire array not the same as sizeof(int)
  4. Means the data will be read byte by byte, this is the pointer required by write as it writes in binary format(byte by byte)
小…红帽 2024-10-23 02:01:11

1) 是的,&_data 是数组第一个元素的地址。
2) 不,write() 会从地址 &_data
开始写入您通过 sizeof(_data) 指定的字节数
3) 如果 _data 是指向数组的指针,则可以传递 sizeof(int)*arrLength,但由于它数组,因此 sizeof() 返回正确的大小。
4)不知道。 ;)

1) Yes, &_data is the address of the first element of your array.
2) No, write() writes the number bytes you have specified via sizeof(_data) starting at address &_data
3) You would pass sizeof(int)*arrLength if _data is a pointer to an array, but since it is an array sizeof() returns the correct size.
4) don't know. ;)

千仐 2024-10-23 02:01:11

阅读此内容: http://www.cplusplus.com/reference/iostream/ostream/write /

  1. 应该是。
  2. 如果你调用“fstream.write(a,b)”,那么它将从位置 a 开始写入 b 个字节到文件中(即地址指向的位置);
  3. 它应该是以字节或字符为单位的大小。
  4. 不多,类似于在更文明的语言中将东西转换为 byte[]。

顺便说一句,它只适用于其中包含简单值的简单数组...

我建议您查看>> <<运营商。

read this : http://www.cplusplus.com/reference/iostream/ostream/write/

  1. should be.
  2. if you call "fstream.write(a,b)" then it writes b bytes starting from location a into the file (i.e. what the address is pointing at);
  3. it should be the size in bytes or chars .
  4. not much, similar to casting stuff to byte[] in more civilized languages.

By the way, it will only work on simple arrays with simple values inside them...

i suggest you look into the >> << operators .

梦萦几度 2024-10-23 02:01:11

&_data 是数组第一个元素的地址吗?

是的。 这是在 C 和 C++ 中将“引用”传递给数组的常用方法。如果您将数组本身作为参数传递,则整个数组内容将被复制,这通常是浪费且不必要的。 更正:您可以传递 &_data,或只是 _data。无论哪种方式,数组都不需要复制到堆栈中。

无论它是什么地址,是否意味着我们只保存数组的地址?那为什么我把他从内存中删除后仍然可以访问数组呢?

不,该方法使用它获得的地址来读取数组内容;正如您所指出的,仅保存内存地址是没有意义的。

我不应该传递 sizeof(_data)*arrLength 吗?我是说...
传递大小的逻辑是什么
int(在本例中)而不是大小
整个数组?

不,sizeof(_data) 是数组的大小,而不是单个成员的大小。无需乘以长度。

处理地址时,转换为 char* 意味着什么?

转换为 char* 意味着该数组作为字节列表进行访问;这是访问和写入原始值所必需的。

is &_data the address to the first element of the array?

Yes, it is. This is the usual way to pass a "reference" to an array in C and C++. If you passed the array itself as a parameter, the whole array contents would be copied, which is usually wasteful and unnecessary. Correction: You can pass either &_data, or just _data. Either way, the array does not need to be copied to the stack.

whatever address it is, does that mean that we only save the address of the array? then how come I still can access the array after I delete him from the memory?

No, the method uses the address it gets to read the array contents; just saving the memory address would be pointless, as you point out.

Shouldn't I pass sizeof(_data)*arrLength? I mean...
what is the logic of passing the size
of int (in this case) and not the size
of the entire array?

No, sizeof(_data) is the size of the array, not of one member. No need to multiply by length.

What does casting into char* means when dealing with addresses?

Casting to char* means that the array is accessed as a list of bytes; that's necessary for accessing and writing the raw values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文