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

时间:2015-09-27 01:01:30

标签: c realloc

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

我有一个动态分配的char *数组,称为“frags”。我还有一个名为“组合”的char *,它指向一些表示新片段的字符串文字。我想用“组合”的内容替换“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];
}

1 个答案:

答案 0 :(得分:1)

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