【发布时间】:2019-05-23 21:37:50
【问题描述】:
我编写了一个函数,它尝试使用动态内存分配连接两个字符串。我可以理解,如果我使用定义的 char 数组会更容易,但我会学习如何在 C 中管理内存。
问题很简单...用 valgrind 运行程序我发现了不同的错误,如下所示:
- 大小为 1 的无效写入
- 大小为 1 的读取无效
- 地址 .... 为 0 字节 [在|内部] 大小为 4 的块已分配。
我试图找出问题所在,我做到了,但我不明白出了什么问题。
解决这个问题对我来说很重要,所以我可以继续做作业并检查错误。
这是代码
void _join(char *s1, char *s2)
{
int i = 0;
int len = strlen(s1);
while (i < strlen(s2)){
s1 = realloc(s1, (len + i)*sizeof(char));
s1[len + i]= s2[i];
i++;
}
// I insert that after, but I don't know if it's necessary
s1 = realloc(s1, (len + i + 1)*sizeof(char));
s1[len + i] = '\0';
}
代码从第 48 行到第 58 行。
我是这样从main调用函数
_join(s1, s2);
其中 s1 和 s2 由输入给出。然后我在 s1 和 s2 上调用 free 函数,因为我在那里用 malloc 创建了。
valgrind 输出的 sn-ps
Before: hello
==11005== Invalid write of size 1
==11005== at 0x109322: _join (changeJOIN.c:53)
==11005== by 0x1091E9: main (changeJOIN.c:22)
==11005== Address 0x4a41be4 is 0 bytes after a block of size 4 alloc'd
==11005== at 0x4839D7B: realloc (vg_replace_malloc.c:826)
==11005== by 0x1092FB: _join (changeJOIN.c:52)
==11005== by 0x1091E9: main (changeJOIN.c:22)
==11005==
...其他错误...
==11005==
==11005== HEAP SUMMARY:
==11005== in use at exit: 9 bytes in 1 blocks
==11005== total heap usage: 17 allocs, 17 frees, 2.109 bytes allocate
==11005==
==11005== 9 bytes in 1 blocks are definitely lost in loss record 1 of 1
==11005== at 0x4839D7B: realloc (vg_replace_malloc.c:826)
==11005== by 0x10935B: _join (changeJOIN.c:56)
==11005== by 0x1091E9: main (changeJOIN.c:22)
【问题讨论】:
-
您可以
realloc(s1, len + sizeof(s2) +1);然后循环(或memcpy)将s2复制到s1中,而不是多次调用realloc。节省大量时间。 -
您正在分配
N字节并将其写入过去。对于这样大小的数组,您可以使用的最大索引是多少? -
首先,您的函数不返回
char,尽管它的原型。其次,效率非常低。第三,也是最重要的,realloc使s1的原始值无效,但更改不会传播给调用者。一个简单的解决方案:将s1作为char*返回并在调用者处释放它。 -
更糟糕的是,它可能会使用在
realloc之后为s1分配的相同存储空间,让您认为您的程序在它不工作的情况下可以工作。 -
我忘了
strcat。这是将s2附加到调整大小的s1的另一个简单解决方案