void operation2(char **p, int n, char *sir) {
    int i, move, k, xlen, ylen;
    char *x, *y, *q, separatori[] = " \'\",!?";
    x = strtok(sir, " ");
    y = strtok(NULL, " ");
    xlen = strlen(x);
    ylen = strlen(y);
    move = ylen - xlen;
    for (i = 0; i < n; i++) {
        k = 0;
        while (strstr(p[i] + k, x)) {
            q = strstr(p[i] + k, x);
            if ((strchr(separatori, *(q - 1)) || q == p[i]) &&
                (*(q + xlen) == '\0' || strchr(separatori, *(q + xlen)))) {
                if (move > 0 && k == 0)
                    p[i] = realloc(p[i], (strlen(p[i]) + move * counter(p[i], x) + 1) * sizeof(char));
                q = strstr(p[i] + k, x);
                memmove(q + xlen + move, q + xlen, strlen(q + xlen) + 1);
                memcpy(q, y, ylen);
                k = strlen(p[i]) - strlen(q) + ylen;
                if (move < 0)
                    p[i] = realloc(p[i], (strlen(p[i]) + move + 1) * sizeof(char));
            } else
                k = k + xlen;
        }
        puts(p[i]);
    }
}

这段代码的目的是在动态分配的文本中查找一个单词(x)并将其替换为另一个单词(y)。它们以字符串(**p)的形式出现,并且是分开的。
sir存储获得的单词之间的差异。move表示文本中的行数。
单词n不能在另一个单词内,因此需要检查分隔符。
如果满足条件,则根据x是正的还是负的,重新分配字符串。如果它是正的,那么字符串将更长,并且可以重新分配给它内部的所有单词move的幻影。x是一个计算字符串中的幻影的函数。
counter为负时,必须减小字符串,以便在操作发生后完成重新分配。
movememmove完成替换。
memcpyk出现后的位置。
在测试过程中,需要用x替换"o"
这是参考资料
Reference
这就是我得到的
Result
当替换字符串中间的"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"时,发生错误,指向下一行的指针丢失,指向上一行的结束部分。1表示以下行的计数器值
"o"是否使用已分配的内存,这样做会丢失下一个指针?
编辑:下面是数组的分配:
int n, i;
scanf("%d", &n);
char **p, *aux;
p = malloc(n * sizeof(char *));
aux = malloc(12000 * sizeof(char));
getchar();
for (i = 0; i < n; i++) {
    fgets(aux, 12000, stdin);
    p[i] = malloc((strlen(aux) + 1) * sizeof(char));
    strcpy(p[i], aux);
    p[i][strlen(p[i]) - 1] = '\0';
}
free(aux);

最佳答案

您的代码非常混乱,因为有太多的副作用,对strlen的多余调用。。。
主要问题是您没有为字符串分配足够的空间:您忘记了'\0'终止符所需的额外字节。
在分析文件时,在主例程中会犯这个错误。
当你吃了这条线后你又来了。
当您realloc行的内容时,也会忘记包含空字节。
先解决这些问题。可能还有其他的,但是您需要简化代码才能看到它们。阅读所有评论,有很多提示。
编辑:您已将代码修复到位,这可能会使此问题的其他读者感到困惑,但在第二次调用memmove时仍有错误:

p[i] = realloc(p[i], (strlen(p[i]) + move + 1) * sizeof(char));

是不正确的,因为您已经缩短了行,因此realloc是新的长度。简单地写下:
p[i] = realloc(p[i], strlen(p[i]) + 1);

编辑:这里有一个更简单的strlen(p[i])版本,它修复了评论中的大多数注释。我没有使用operation2,因为您没有发布代码,所以我不能断言is做了正确的事情。
void operation2(char **p, int n, char *sir) {
    int i, move, k, xlen, ylen;
    static const char separatori[] = " \'\",!?";
    char *x, *y, *q;

    x = strtok(sir, " ");
    y = strtok(NULL, " ");
    xlen = strlen(x);
    ylen = strlen(y);
    move = ylen - xlen;
    for (i = 0; i < n; i++) {
        k = 0;
        while ((q = strstr(p[i] + k, x)) != NULL) {
            k = q - p[i];
            if ((q == p[i] || strchr(separatori, q[-1])) &&
                (q[xlen] == '\0' || strchr(separatori, q[xlen]))) {
                if (move > 0) {
                    p[i] = realloc(p[i], strlen(p[i]) + move + 1);
                    q = p[i] + k;
                }
                memmove(q + ylen, q + xlen, strlen(q + xlen) + 1);
                memcpy(q, y, ylen);
                k += ylen;
                if (move < 0) {
                    p[i] = realloc(p[i], strlen(p[i]) + 1);
                }
            } else {
                k += xlen;
            }
        }
        puts(p[i]);
    }
}

关于c - 使用realloc后,数组中的下一个指针丢失,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34144986/

10-11 23:08
查看更多