C语言 在数组中的char *上使用realloc会改变该数组外的数据



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

我有一个名为"frags"的动态分配char *数组。我也有一个字符*称为"组合",它指向一些字符串字面值,代表一个新的片段。我想将"frags"中的一个片段替换为"combination"的内容。我的项目是结构化的,我将frags数组、要替换的frags索引和组合字符串发送到函数中。在这个函数中,我有:

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

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

奇怪的是,printf's并不打印相同的东西。第一个printf输出的结果是"hello",这是正确的,但是第二个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: %sn", *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: %dn", currentRound, combination, max);
                        index1 = i; index2 = j;
                    } 
                }
            }
            // merge 
            mergeFrags(frags, index1, index2, combination);
            currNumFrags--;
        }
    }

    return frags[0];
}

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

最新更新