为什么保存 IP 的字符串需要 15 字节,而大小只有 4
Why does string holding an IP require 15 byte when the size is only 4?
根据我的理解,C++中的char
需要 1 个字节。因此,保存 IP 地址的字符串的大小应为 15 字节。请考虑以下代码:
char *temp = new char[15];
ifstream iss("file.txt"); //contains an ip address
iss >> temp;
cout << "temp : "<< temp << " ";
cout << sizeof (temp) << endl;
它显示大小为 4。有人可以解释一下为什么吗?
然后我尝试了相同的方法,只是这次我只分配了 4 个字节来temp
:
char *temp = new char[4];
此时间结果是之前的结果,附加了:
*** glibc detected *** /home/HelloWorld: double free or corruption (out): 0x08557030 ***
======= Backtrace: =========
/lib/i386-linux-gnu/libc.so.6(+0x75ee2)[0xb758bee2]
/lib/i386-linux-gnu/libc.so.6(fclose+0x154)[0xb757b424]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSt12__basic_fileIcE5closeEv+0x47)[0xb7746b87]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSt13basic_filebufIcSt11char_traitsIcEE5closeEv+0x98)[0xb7784328]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZNSt14basic_ifstreamIcSt11char_traitsIcEED1Ev+0x3f)[0xb77846af]
/home/HelloWorld[0x8048e2d]
/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf3)[0xb752f4d3]
/home/HelloWorld[0x8048ab1]
======= Memory map: ========
08048000-0804a000 r-xp 00000000 08:01 536973 /home/HelloWorld
0804a000-0804b000 r--p 00001000 08:01 536973 /home/HelloWorld
0804b000-0804c000 rw-p 00002000 08:01 536973 /home/HelloWorld
08557000-08578000 rw-p 00000000 00:00 0 [heap]
b74e8000-b74ea000 rw-p 00000000 00:00 0
b74ea000-b7514000 r-xp 00000000 08:01 655846 /lib/i386-linux-gnu/libm-2.15.so
b7514000-b7515000 r--p 00029000 08:01 655846 /lib/i386-linux-gnu/libm-2.15.so
b7515000-b7516000 rw-p 0002a000 08:01 655846 /lib/i386-linux-gnu/libm-2.15.so
b7516000-b76ba000 r-xp 00000000 08:01 655851 /lib/i386-linux-gnu/libc-2.15.so
b76ba000-b76bc000 r--p 001a4000 08:01 655851 /lib/i386-linux-gnu/libc-2.15.so
b76bc000-b76bd000 rw-p 001a6000 08:01 655851 /lib/i386-linux-gnu/libc-2.15.so
b76bd000-b76c1000 rw-p 00000000 00:00 0
b76c1000-b76dc000 r-xp 00000000 08:01 655821 /lib/i386-linux-gnu/libgcc_s.so.1
b76dc000-b76dd000 r--p 0001a000 08:01 655821 /lib/i386-linux-gnu/libgcc_s.so.1
b76dd000-b76de000 rw-p 0001b000 08:01 655821 /lib/i386-linux-gnu/libgcc_s.so.1
b76de000-b77bb000 r-xp 00000000 08:01 792998 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18
b77bb000-b77bf000 r--p 000dc000 08:01 792998 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18
b77bf000-b77c0000 rw-p 000e0000 08:01 792998 /usr/lib/i386-linux-gnu/libstdc++.so.6.0.18
b77c0000-b77c7000 rw-p 00000000 00:00 0
b77d5000-b77d9000 rw-p 00000000 00:00 0
b77d9000-b77da000 r-xp 00000000 00:00 0 [vdso]
b77da000-b77fa000 r-xp 00000000 08:01 655841 /lib/i386-linux-gnu/ld-2.15.so
b77fa000-b77fb000 r--p 0001f000 08:01 655841 /lib/i386-linux-gnu/ld-2.15.so
b77fb000-b77fc000 rw-p 00020000 08:01 655841 /lib/i386-linux-gnu/ld-2.15.so
bff69000-bff8a000 rw-p 00000000 00:00 0 [stack]
我猜这是因为内存分配不足。有人可以解释一下这里是如何管理内存的吗?
temp
的类型是char *
,所以sizeof (temp)
得到指针的大小,通常与机器的字大小相同,即 32 位机器为 4 字节,64 位机器为 8 字节。
若要获取 C 样式字符串的长度,请使用 std::strlen(temp)
from <cstring>
通过使用 sizeof(temp)
,您最终会得到指针的大小,在 32 位系统上为 4 个字节。
发生损坏是因为您为堆上的 char 数组分配了 4 个字节,然后尝试用文件中的 15 字节数据填充它,从而导致损坏。
这与写入任何数字相同 - 要写入 221,您需要 3 个字符,因为我们使用的是十进制系统。但是,您可以用二进制编写 221 并将其放在一个字节中:二进制11011101
、十六进制DD
。根据您使用的系统类型,数字的表示形式在长度上有所不同。通常,每个字符的可能性越多(2 vs 10 vs 16),字符串就越短。
您可能会说将数字写为字符串效率低下。过去这样做的每个位都没有充分利用。谷歌Information Theory
,一切都会得到解释。
还有一个更有趣的例子:通常人们用手指数到 10 个——因为他们有 10 个手指。但是使用二进制代码,您可以在手指上数到 1023 个!
相关文章:
- 从不同线程使用int64的不同字节安全吗
- 将Integer转换为4字节的unsined字符矢量(按大端字节顺序)
- 在UNIX系统中使用DIR查找文件的字节大小
- 如何使用Crypto++并为RSA返回可打印的字节/字符数组
- std::当在256字节边界上写入整数时,流的奇怪行为
- 当比特(而不是字节)的顺序至关重要时的持久性
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 如何在文件中查找字节序列
- luaL_dofile在已知良好的字节码上失败,可以使用未编译的版本
- 字节到位运算符重载C++
- 在java中读取c++字节的位字段
- 我正在开发服务器,ip作为参数传递不起作用
- 检查 IP 第一个八位字节是否不以 127 / 224 或 255 开头
- 如何将C++ ulong 4 字节 IP 地址正确转换为 C# 类型
- C++:在tcp/ip上发送字节时使用矢量的最佳方式
- 为什么保存 IP 的字符串需要 15 字节,而大小只有 4
- C++如何将 IP 地址转换为字节
- iPhone TCP-IP字节顺序映射
- 获取我的IP地址并使用c++将其转换为字节
- 正在将IP地址字节转换为整数