c - 在数组内的 char * 上使用 realloc 会更改该数组外部的数据

标签 c realloc

我观察到一些关于 realloc 的非常奇怪的行为......我想知道你们是否可以帮助我。

我有一个动态分配的 char * 数组,称为“frags”。我还有一个名为“combination”的 char * ,它指向一些表示新片段的字符串文字。我想用“combination”的内容替换“frags”中的片段之一。我的项目的结构方式是,我将 frags 数组、要替换的 frag 的索引和组合字符串发送到函数中。在这个函数中我有:

printf("combination before realloc: %s\n", combination);
char *newString = (char *) realloc(frags[firstIndex], strlen(combination) + 1);
assert(newString != NULL);
printf("combination after realloc: %s\n", combination);


strcpy(newString, combination);
frags[firstIndex] = newString;

奇怪的是,printf 不打印相同的内容。第一个 printf 产生“hellol”,这是正确的,但下一个 printf 产生乱码 - 类似于“{?`?p??”。因此,问题在于对 realloc 的调用。老实说,我不知道发生了什么事。似乎对 realloc 的调用以某种方式扰乱了组合,但我认为如果可能发生这种情况,那么它会返回 NULL?

请帮助我:(

编辑:添加代码

bool findMaxOverlap(char *first, char *second, char **combination, int *roundMax) {
    // setup lng and shrt
    char *lng, *shrt;
    if (strlen(first) >= strlen(second)) { lng = first; shrt = second; }
    else { lng = second; shrt = first; }
    int shrtLen = strlen(shrt), lngLen = strlen(lng);

    // check if lng contains shrt
    if (strstr(lng, shrt) != NULL && shrtLen > *roundMax) {  
        *combination = lng;
        *roundMax = shrtLen;
        return true;
    }
    else // check if lng's tail ends contain part of shrt

    {                              
        int numChars = shrtLen - 1, max = 0, shrtOffset = 0, lngOffset = 0;
        for (int i = 0; i < shrtLen && numChars > *roundMax && numChars > max; i++) {
            numChars = shrtLen - 1 - i;
            for (int j = 0; j < lngLen; j++) {
                if (strncmp(shrt + i, lng + j, numChars) == 0) {
                    max = numChars;
                    shrtOffset = i;
                    lngOffset = j;
                }
            }
        }
        if (shrtOffset > lngOffset) {
            // short first
            char newFrag[lngLen + shrtOffset + 1];  
            strncpy(newFrag, shrt, shrtOffset);
            strcat(newFrag, lng + shrtOffset);
            *combination = newFrag;
            *roundMax = numChars;
            return true;
        } else {
            // lng first

            char newFrag[lngLen + (shrtLen - numChars) + 1];
            strcpy(newFrag, lng);
            strcat(newFrag, shrt + numChars);

            *combination = newFrag;
            printf("combination in findmax is: %s\n", *combination);
            *roundMax = numChars;
            return true;
        }
    }
    return false;
}

void mergeFrags(char *frags[], int index1, int index2, char *combination) {

    int firstIndex, secondIndex;
    if (index1 < index2) {
        firstIndex = index1;
        secondIndex = index2;
    } else {
        firstIndex = index2;
        secondIndex = index1;
    }

    char temp[strlen(combination) + 1];
    strcpy(temp, combination);

    char *newString = (char *) realloc(frags[firstIndex], strlen(combination) + 1);
    assert(newString != NULL);

    strcpy(newString, temp);
    frags[firstIndex] = newString;
    free(frags[secondIndex]);

}

char *reassemble(char *frags[], int numFrags) {

    if (numFrags > 1) {
        char *combination;
        int max, index1, index2, currNumFrags = numFrags;

        for (int currentRound = 0; currentRound < numFrags - 1; currentRound++) {
            max = index1 = index2 = 0, combination = NULL;

            for (int i = 0; i < currNumFrags; i++) {
                for (int j = i+1; j < currNumFrags; j++) {
                    //find max overlap of pair
                    if (findMaxOverlap(frags[i], frags[j], &combination, &max)) {
                        printf("round #: %d, combination: %s, max: %d\n", currentRound, combination, max);
                        index1 = i; index2 = j;
                    } 
                }
            }
            // merge 

            mergeFrags(frags, index1, index2, combination);
            currNumFrags--;
        }
    }


    return frags[0];
}

最佳答案

您说过(在上面的评论中)您使用 strdup 来分配 combination 中的数据,但您真正做的是设置 combination 指向堆栈上的数据。 findMaxOverlap 返回后,您现在指向堆栈上未分配的空间,这为您提供了您所看到的未定义行为。当调用realloc时,堆栈中的区域被重用,并且combination的值看起来像垃圾。

关于c - 在数组内的 char * 上使用 realloc 会更改该数组外部的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32803549/

相关文章:

C程序计算数据类型的范围

c - 在子进程中调用 execlp() 后如何打印 f()?

c - strlen 没有产生正确的数字并且 strncpy 不起作用

c++ - 结构体声明中的冒号是什么意思,例如 :1, :7, :16, 或 :32?

c - 在 C 中扩展矩阵

c - 我应该如何在心理上解析这个陈述?

c - 我在下面的代码中被中止(核心转储)

fclose 后无法释放 fileName char *

c - 将动态数组传递给 C 中的函数

c - 如果像这样初始化,则重新分配二维数组 : char (*A)[size] = malloc(sizeof(char[size][size]))