在編寫一個(gè)動態(tài)二維數(shù)組并且需要將其初始化時(shí),出現(xiàn)了問題,相關(guān)部分如下:
maze = new char*[m + 2];
for (int i = 0; i <= m + 2; i++) {
maze[i] = new char[n + 2];
}
memset(maze[i], '#', (n + 2) * sizeof(char));
編譯可以通過,debug時(shí)發(fā)現(xiàn)錯(cuò)誤在于數(shù)組越界(在后續(xù)調(diào)用這個(gè)數(shù)組時(shí)出現(xiàn)了錯(cuò)誤,提示訪問地址出錯(cuò))
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
scanf_s("%c", &maze[i][j]);//報(bào)錯(cuò)
//找到起點(diǎn)的位置
if (maze[i][j] == 'S') {
pos_m = i;
pos_n = j;
}
}//for:j
getchar();//getchar吃掉回車符
}//for:i
先看微軟官方對memset的解釋
Microsoft Docs memset
具體原因如下:
- memset函數(shù)只能夠?qū)B續(xù)的內(nèi)存空間進(jìn)行初始化。如果使用new()函數(shù)或是malloc()函數(shù)分配的內(nèi)存可能會不連續(xù),因此初始化時(shí)會出現(xiàn)錯(cuò)誤。
- 而如果是申請一個(gè)靜態(tài)的數(shù)組如maze[25][25],其內(nèi)存肯定是連續(xù)的,此時(shí)對maze()使用memset是不會出現(xiàn)錯(cuò)誤的。
正確的使用方法:
因?yàn)槭莔aze[i]相當(dāng)于一個(gè)指向一個(gè)一維數(shù)組的指針,對每一個(gè)數(shù)組指針maze[i]開辟一個(gè)一維數(shù)組緊接著對這個(gè)一維數(shù)組進(jìn)行初始化。
舉例:
char **maze = new char*[m+2];
for (int i = 0; i <=m+2; i++) {
maze[i] = new char[n+2];
memset(maze[i], '#', (n + 2) * sizeof(char));
}
特此做記錄,避免重復(fù)踩坑。