在数组内的 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
的值看起来像垃圾。
我观察到一些关于 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
的值看起来像垃圾。