c - 为什么写入另一个数组成员会导致问题?
问题描述
以下代码似乎运行良好:
char **func()
{
char **s = malloc(sizeof(char) * 5);
s[0] = "1101";
s[1] = "1001";
s[2] = "0001";
// s[3] = "1100";
return s;
}
int main()
{
char **s;
s = func();
printf("Hello World: %s", s[0]);
free(s);
return 0;
}
但是,如果我取消注释该行s[3] = "1100";
,则会出现错误:
Error in `./a.out': free(): invalid next size (fast): 0x000000000259f010
为什么会这样,即使数组有足够的大小?
解决方案
在这里,您为 5char
秒分配了足够的内存。
char **s = malloc(sizeof(char) * 5);
然而,对于 5 个char
更大的指针来说不是。
让我们假设指针是四个字节(可能是 8...)。字符绝对是 1 个字节。
在这里,您正在写入该内存,大约 4 个字节(因为指针的大小,而不是因为四个字符)。
还不是问题。
s[0] = "1101";
在这里,您正在写入位于高 4 字节地址的内存中。
该地址本身还不是问题,它仍然在 5 个分配的字节内。
但是,在那里写入大于一个字节的内容(您这样做,大小为 4)已经不正确。
s[1] = "1001";
更糟糕的是,在你得到的地址后面 8 个字节,在所有地址后面 3 个字节,总共 4 个字节。非常不正确。
s[2] = "0001";
您可能已经遇到了第二次写入的问题。
第二次和第三次访问没有遇到问题纯属运气。好运或坏运,取决于您喜欢何时发现错误的理念。
要解决此问题,请根据您正在编写的内容分配内存。引用 Barmar 的评论:
sizeof(char) 应该是 sizeof(char *)
如果 malloc 中 sizeof 的参数是一个类型,它应该总是比你分配的类型少一个 *。
来自 Deduplicator(我实际上也更喜欢这个):
我更希望看到 char** s = malloc(5 * sizeof *s);。不必编写类型使其不易出错。
不必键入类型的部分包括指针/星号数量的潜在错误部分。即这个最佳实践会阻止你的问题。
推荐阅读
- excel - Excel,找到第一个和最后一个单元格条目的列并使用另一行的该列位置
- openwrt - 具有多个远程 IP 地址的 OpenVpn 客户端
- office-ui-fabric - 我可以使用 Fluent UI 创建与任何 Microsoft 应用程序无关的网站吗?
- php - 到底是怎么回事?我从未见过这样的 PHP 语法:${"\x47\x4c\x4fB\x41\x4c\x53"}['v9800']
- python - 从文件列和行标题创建嵌套字典
- javascript - 在处理未安装组件的清理时,这些解决方案之间有什么区别?useRef 与布尔变量
- sql - SQL。通过历史性的第一个周来获取用户名收入
- git - 使用core.autocrlf = true时文件的'git hash-object'结果不同?
- ios - Decodebase64 initWithBase64EncodedString 返回 nil
- javascript - Javascript RegExp 在具有嵌套子字符串的字符串上应用跨度标签