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

Using realloc on a char * within an array alters data outside of that array

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

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

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 的调用以某种方式混淆了组合,但我认为如果这可能发生那么它会 return 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 returns 之后,您现在指向堆栈上未分配的 space,这为您提供了您所看到的未定义行为。调用realloc时,栈中的区域被重用,combination的值看起来像垃圾。