我有一些代码给你,希望有人能告诉我,我做错了什么。目前,我正在将我的编程难题移植到其他编程语言中,以便动手。
C 语言中的代码抽象(更新(:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *dummy = "1234567890";
const char* inlet = "_";
void dosomething(int c, char* s){
printf("%sn", s);
if (c < 10) {
char *ns = malloc(sizeof(char)*11);
strncpy(ns, s, c-1);
strncat(ns, inlet, 1);
strcat(ns, &s[c]);
dosomething(c+1, ns);
//free(ns);
}
}
void main() {
for(int i = 0; i < 100; i++) {
char *s = malloc(sizeof(char)*11);
strcpy(s, dummy);
dosomething(1, s);
free(s);
}
}
代码运行良好,直到我在dosomething((方法中取消注释free((调用。这就是我不理解的。在我看来,释放内存绝对没有问题,因为它从递归调用返回后不再使用,但程序输出告诉不同的东西。
没有空闲的输出符合预期:
...
1_34567890
1_34567890
...
使用第二个免费,只产生一个结果,然后程序停止:
*** Error in `./a.out': malloc(): memory corruption (fast): 0x000000000164e0d0 ***
Abgebrochen (Speicherabzug geschrieben)
更新:我根据注释和答案更改了代码,但问题仍然存在。使用 malloc 分配更多内存并不能防止内存错误,如果 dosomething(( 方法中的 free(( 调用被注释。为递归的第一次迭代正确生成输出,第二次显示不同的结果,第三次也是如此,然后程序失败(有关新结果,请参阅函数顶部的新 printf:
输出:
1234567890
_234567890
__34567890
___4567890
____567890
_____67890
______7890
_______890
________90
_________0
1234567890
@@J_234567890
@@J_J_234567890
@@J__J_234567890
@@J___J_234567890
@@J___J_234567890
@@J___J_234567890
@@J____J_234567890
@@J____J_234567890
@@J_____0__234567890
1234567890
@@J_234567890
@@J_J_234567890
@@J__J_234567890
@@J___J_234567890
@@J___J_234567890
@@J___J_234567890
@@J____J_234567890
@@J____J_234567890
@@J_____0__234567890__234567890
*** Error in `./a.out': free(): invalid next size (fast): 0x00000000014a4130 ***
Abgebrochen (Speicherabzug geschrieben)
谁能向我解释一下,我在眨眼什么?
更新2:@Michi和@MichaelWalz已经弄清楚了这一点。它是使用 malloc - 因此在第一次迭代后处理内存中的垃圾(打印内存地址和字符串表明非常整洁(和使用 strcat 之间的组合。
在未初始化的内存上使用 strcat 会将内存中的字符串附加到内存中指针之后找到的下一个"\0"字符。如果未初始化内存,则可能远远超出该字符串的范围。
谢谢你们!
工作代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const char *dummy = "1234567890";
const char* inlet = "_";
void dosomething(int c, char* s){
printf("%p %sn", s, s);
if (c < 10) {
//char *ns = malloc(sizeof(char)*11);
char *ns = calloc(11, sizeof(char));
strncpy(ns, s, c);
strncat(ns, inlet, 1);
strncat(ns, &s[c+1],10-c);
dosomething(c+1, ns);
free(ns);
}
}
void main() {
for(int i = 0; i < 100; i++) {
//char *s = malloc(sizeof(char)*11);
char *s = calloc(11, sizeof(char));
strcpy(s, dummy);
dosomething(0, s);
free(s);
}
}
原因是因为 malloc 函数分配 10 个字符,而需要 11 个字符(以