使用new时将覆盖变量

Variables being overwritten when using new

本文关键字:覆盖 变量 new 使用      更新时间:2023-10-16

我在c++中遇到动态内存分配问题。我必须编写一个函数来解决存储在.dat文件中的迷宫。墙由#组成,用空格隔开,有些点是需要读入任意长度c字符串的单词。然后将这个c字符串存储在迷宫阵列中。我的问题是,我的c字符串不断覆盖内存中以前的字符串。如何告诉程序不要覆盖某些内存块?

这是初始化迷宫阵列的函数:

int LoadMaze(Maze& maze, int& width, int& height, char fname[])
{
    ifstream ifs(fname);
    int stringLength;
    char inputChar;
    char* newCString;
    if (ifs.good())
    {
        ifs >> width >> height;
        maze = new char*[width*height];
        for (int i=0;i<width*height;i++)
        {
            stringLength = 0;
            inputChar = '1';
            while(inputChar != ' ')
            {
                inputChar = ifs.get();
                if(inputChar != ' ' && inputChar != 'n')
                {
                    newCString = resizeChar(newCString, stringLength);
                    newCString[stringLength++] = inputChar;
                }
            }
            //maze = resizeMaze(maze, i);
            maze[i] = newCString;
        }
        ifs.close();
        return 1;
    }
    else
    {
        cerr << "File not found." << endl;
        return 0;
    }
}

由于C字符串必须是任意长度,resizeChar会将cstring大小增加一。然后指向cstring的指针存储在迷宫中。

char* resizeChar(char* stringStart, int oldSize)
{
    int counter = 0;
    char* tempPtr = new char[oldSize + 1];
    for(counter = 0; counter < oldSize; counter++)
    {
        *(tempPtr + counter) = *(stringStart + counter);
    }
    delete[] stringStart;
    return (tempPtr);
}

您正在向函数传递一个未初始化的值:

char* newCString;
....
newCString = resizeChar(newCString, stringLength);

要解决这个问题,您需要给newCString一个合理的初始值,并确保resizeChar能够处理这种情况。

最好每次在循环中初始化newCString。这也避免了对迷宫的每一行使用相同缓冲区的问题。

另一个主要问题是,您永远不会对正在构建的字符串进行null终止。因此,一旦你使用了maze[i] = newCString;,那一行只是指向一些字符,但你已经丢失了字符串中有多少字符的信息。如果您试图输出这个字符串,那么您将缓冲区溢出并开始输出垃圾。

您需要比字符串中的字符数多分配1个字节,并使最后一个字节为''

问题是如何阻止newCString的新值被写入与以前相同的内存位置?

如果将变量的旧值替换为新值,则旧值将被覆盖,因为变量在其生命周期内不会在内存中移动。如果你不想更改值,就不要编写更改它的代码。将newCString的值设置为你希望它保持的值,并且不要从那时起更改它的值。