如何修复 g++ 内存范围重叠?
Posted
技术标签:
【中文标题】如何修复 g++ 内存范围重叠?【英文标题】:How do I fix a g++ memory range overlap? 【发布时间】:2014-11-22 07:48:56 【问题描述】:我开发了一个在 Visual Studio 中完美运行的 C++ 程序,它接受一个整数数组、两个 C 字符串数组和一个大 C 字符串,并尝试查找大 C 字符串是否包含其中的任何其他 C 字符串有一定的距离。
编辑:由于这是一项学校作业,我被限制使用 C 字符串而不是 std::string 和 strcopy 而不是 memmove。
当我在 g++ 上运行程序时,我收到以下错误消息:
==17764==ERROR: AddressSanitizer: strcpy-param-overlap: memory ranges [0x7fff7213d993,0x7fff7213d994) and [0x7fff7213d993, 0x7fff7213d994) overlap
#0 0x7fa2141eec11 in __interceptor_strcpy ../../../../gcc-4.9.2/libsanitizer/asan/asan_interceptors.cc:486
#1 0x402b2a in standardizeRules(int*, char (*) [21], char (*) [21], int) (/w/home.02/cs/ugrad/justinn/match+0x402b2a)
#2 0x40176d in main (/w/home.02/cs/ugrad/justinn/match+0x40176d)
#3 0x376f01ed1c in __libc_start_main (/lib64/libc.so.6+0x376f01ed1c)
#4 0x4011f8 (/w/home.02/cs/ugrad/justinn/match+0x4011f8)
Address 0x7fff7213d993 is located in stack of thread T0 at offset 787 in frame
#0 0x401347 in main (/w/home.02/cs/ugrad/justinn/match+0x401347)
This frame has 7 object(s):
[32, 48) 'test1dist'
[96, 144) 'distance'
[192, 276) 'test1w1'
[320, 404) 'test1w2'
[448, 577) 'doc'
[640, 892) 'word1' <== Memory access at offset 787 is inside this variable
[928, 1180) 'word2'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
Address 0x7fff7213d993 is located in stack of thread T0 at offset 787 in frame
#0 0x401347 in main (/w/home.02/cs/ugrad/justinn/match+0x401347)
This frame has 7 object(s):
[32, 48) 'test1dist'
[96, 144) 'distance'
[192, 276) 'test1w1'
[320, 404) 'test1w2'
[448, 577) 'doc'
[640, 892) 'word1' <== Memory access at offset 787 is inside this variable
[928, 1180) 'word2'
HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: strcpy-param-overlap ../../../../gcc-4.9.2/libsanitizer/asan/asan_interceptors.cc:486 __interceptor_strcpy
==17764==ABORTING
是什么导致了这个错误,我该如何解决?
谢谢!
编辑: 代码如下:
int standardizeRules(int distance[], char word1[][MAX_WORD_LENGTH + 1], char word2[][MAX_WORD_LENGTH + 1], int nRules)
int validCheck = nRules; //validCheck holds the number of actual valid rules to avoid checking known bad rules
for (int a = 0; a < validCheck; a++) //converts every letter in every string to lowercase
for (int b = 0; b < MAX_WORD_LENGTH; b++)
word1[a][b] = tolower(word1[a][b]);
word2[a][b] = tolower(word2[a][b]);
for (int count = 0; count < validCheck; count++) //repeat rule testing, if a repeat is found it sets distance to 0 so code automatically filters it out
for (int x = count + 1; x < validCheck; x++) //compares current string to all other strings behind it in both arrays
bool repeat = false;
//cerr << "Testing: " << x << endl;
if (strcmp(word1[count], word1[x]) == 0)
if (strcmp(word2[count], word2[x]) == 0)
//cerr << "Repeat rule" << endl;
repeat = true;
else if (strcmp(word1[count], word2[x]) == 0)
if (strcmp(word2[count], word1[x]) == 0)
//cerr << "Repeat rule" << endl;
repeat = true;
else if (strcmp(word2[count], word1[x]) == 0)
if (strcmp(word1[count], word2[x]) == 0)
//cerr << "Repeat rule" << endl;
repeat = true;
else if (strcmp(word2[count], word2[x]) == 0)
if (strcmp(word1[count], word1[x]) == 0)
//cerr << "Repeat rule" << endl;
repeat = true;
if (repeat) //tests to see which distance is lesser, then sets that to 0
//cerr << "Repeat testing" << endl;
if (distance[count] < distance[x])
distance[count] = 0;
else
distance[x] = 0;
//cerr << "X:" << x << endl;
//cerr << "Done with repeat" << endl;
bool replace = false;
if (distance[count] < 1) //non-positive distance check
//cerr << "Bad distance: " << distance[count] << endl;
replace = true;
if (strlen(word1[count]) == 0 || strlen(word2[count]) == 0) //empty string check
//cerr << "Empty string" << endl;
replace = true;
for (int charPos = 0; charPos < MAX_WORD_LENGTH; charPos++) //non-alphabetical check
if (word1[count][charPos] != '\0' && word2[count][charPos] != '\0')
if (!(isalpha(word1[count][charPos]) && isalpha(word2[count][charPos])))
//cerr << "Bad character 1: " << word1[count][charPos] << ", Bad character 2: " << word2[count][charPos] << endl;
replace = true;
if (replace) //if bad rule, swaps current rule with last valid (or unchecked) rule
//cerr << "Begin" << endl;
for (int x = 0; x < validCheck; x++)
//cerr << "Dist: " << distance[x] << ", word1: " << word1[x] << ", word2: " << word2[x] << endl;
//cerr << endl;
int distReplace = distance[validCheck - 1];
distance[validCheck - 1] = distance[count];
distance[count] = distReplace;
char word1Rep[MAX_WORD_LENGTH + 1];
char word2Rep[MAX_WORD_LENGTH + 1];
strcpy(word1Rep, word1[validCheck - 1]);
strcpy(word2Rep, word2[validCheck - 1]);
strcpy(word1[validCheck - 1], word1[count]);
strcpy(word2[validCheck - 1], word2[count]);
strcpy(word1[count], word1Rep);
strcpy(word2[count], word2Rep);
for (int x = 0; x < validCheck; x++)
//cerr << "Dist: " << distance[x] << ", word1: " << word1[x] << ", word2: " << word2[x] << endl;
validCheck--;
count--;
//cerr << "End" << endl;
for (int x = 0; x < validCheck; x++)
//cerr << "Dist: " << distance[x] << ", word1: " << word1[x] << ", word2: " << word2[x] << endl;
//cerr << "validCheck: " << validCheck << endl;
return validCheck;
int determineQuality(const int distance[], const char word1[][MAX_WORD_LENGTH + 1], const char word2[][MAX_WORD_LENGTH + 1], int nRules, const char document[])
//cerr << "Checkpoint A" << endl;
int quality = 0; //counter for matches
char words[200][200]; //array to hold all words in document
int count = 0;
int arrayPos = 0;
while (count < strlen(document)) //loop through document
//cerr << "Checkpoint B" << endl;
int charPos = 0;
while (count < strlen(document) && document[count] != ' ') //split document up into words and record words in array
//cerr << "Checkpoint C: " << count << endl;
if (isalpha(document[count]) && charPos < 200) //record only alphabetical characters
words[arrayPos][charPos] = tolower(document[count]);
charPos++;
count++;
count++;
words[arrayPos][charPos] = '\0'; //end each word with a null byte
//cerr << "Word: " << words[arrayPos] << endl;
arrayPos++;
for (int ruleCount = 0; ruleCount < nRules; ruleCount++) //compare rules to words
bool match = false; //boolean to record if rule has a match or not
for (int wordCount = 0; wordCount <= arrayPos; wordCount++)
if (strcmp(word1[ruleCount], words[wordCount]) == 0) //if word1 finds a match, look for a match for word2 within distance
int beginning = wordCount - distance[ruleCount];
if (beginning < 0)
beginning = 0;
int end = wordCount + distance[ruleCount];
if (end >= arrayPos)
end = arrayPos;
for (int arrayCheck = beginning; arrayCheck <= end; arrayCheck++)
if (strcmp(word2[ruleCount], words[arrayCheck]) == 0)
match = true;
if (strcmp(word2[ruleCount], words[wordCount]) == 0) //if word2 find a match, look for a match for word1 within distance
int beginning = wordCount - distance[ruleCount];
if (beginning < 0)
beginning = 0;
int end = wordCount + distance[ruleCount];
if (end >= arrayPos)
end = arrayPos;
for (int arrayCheck = beginning; arrayCheck <= end; arrayCheck++)
if (strcmp(word1[ruleCount], words[arrayCheck]) == 0)
match = true;
if (match) //if rule had a match, increment quality
quality++;
return quality;
【问题讨论】:
使用 valgrind 并使用所有警告和调试信息 (gcc -Wall -Wextra -g
) 编译您的代码。还可以使用调试器 (gdb
),尤其是它的观察点。你可能在某处有一些undefined behavior!
显示你的源代码。看起来您错误地使用了strcpy
(内存区域重叠)。考虑使用memmove
。顺便说一句,在 C++ 中你应该使用 std::string
听起来像缓冲区溢出,这意味着您正在访问数组边界之外的数组索引。可能你刚刚在 Visual Studio 中走运了。不看代码有点难说。
尝试找出源代码中的违规部分,并在您的问题中添加MCVE。
请出示你的standardizeRules
函数。
【参考方案1】:
感谢您的帮助。
经过进一步调查,我发现该错误是由于使用 strcpy() 与源地址相同。
【讨论】:
以上是关于如何修复 g++ 内存范围重叠?的主要内容,如果未能解决你的问题,请参考以下文章