c - valgrind 在分配的内存中写入大小为 8 的无效
问题描述
我正在尝试将新节点添加到我的链表中,但它会出现内存错误
我的结构和全局变量:
typedef struct word word;
struct word
{
char str[256];
word *next;
};
word *head = NULL;
word *cur = NULL;
功能 :
int addWord(char * str)
{
word *w = calloc(1, sizeof(w));
if(w == NULL)
{
return 0;
}
strcpy(w->str, str);
if(cur == NULL)
{
cur = w;
head = w;
}
else
{
puts("4");
cur->next = w;
puts("5");
cur = w;
puts("6");
}
return 1;
}
结果是:
...
4
5
6
4
==73913== Invalid write of size 8
==73913== at 0x109425: addWord (in /home/mz37/programming/godaphy/bin/godaphy.out)
==73913== by 0x109696: parseLine (in /home/mz37/programming/godaphy/bin/godaphy.out)
==73913== by 0x109351: main (in /home/mz37/programming/godaphy/bin/godaphy.out)
==73913== Address 0x4a6a880 is 96 bytes inside an unallocated block of size 4,188,096 in arena "client"
==73913==
5
6
我仍在寻找错误,我还没有找到它
解决方案
word *w = calloc(1, sizeof(w));
该w
变量是word
指针类型,因此最多可能是四个或八个字节。如果我们最终使用 128 位机器,它可能会更大,但要达到 2000 多位还需要一段时间 :-)
你可能想做:
word *w = calloc(1, sizeof(*w));
// note this ___^
的类型*w
是实际的类型word
,这将是您尝试执行的正确大小。
而且,顺便说一句,您可能想考虑盲目地将给定的任何字符串复制到只能容纳 256 个字符的内存块中的智慧。更安全的选择是:
strncpy(w->str, str, sizeof(w->str) - 1);
// Would normally also do something like:
// w->str[sizeof(w->str) - 1] = '\0';
// but calloc() makes that superfluous.
结果函数(包括紧缩)将遵循以下几行:
int addWord(char *str) {
word *w;
// Option to fail if string too big, rather than truncate.
//if (strlen(str) >= sizeof(w->str)
// return 0;
// Allocate and check.
if ((w = calloc(1, sizeof(*w))) == NULL)
return 0;
// Copy in string, truncate if too big.
strncpy(w->str, str, sizeof(w->str) - 1);
// Make new list if currently empty, otherwise add it, then flag success.
if(cur == NULL) {
cur = head = w;
} else {
cur->next = w;
cur = w;
}
return 1;
}
推荐阅读
- vue.js - VueJS 过渡组不适用于图像,我该如何淡化图像?
- java - 在firebase中注册后如何登录?
- javascript - Javascript SPA(电子)添加登录屏幕
- java - Java将负数变为-1,将正数变为1
- amazon-web-services - Cloudfront - 如何将签名的 url 传播到所有网站请求?
- nginx - Nginx - 上游配置问题
- node.js - 以不超过几分钟的延迟观看 Twitter 时间线以获取新推文
- linked-list - 问题是检查给定的链表是否是回文。请告诉我我做错了什么?
- reactjs - React:如何通过 api 调用更改按钮的状态?
- javascript - 如何通过函数更改javascript中的数组值?