使用new时会覆盖变量

时间:2014-09-14 03:45:09

标签: c++ memory dynamic overwrite

我在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大小增加1。然后指向该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);
}

2 个答案:

答案 0 :(得分:2)

您正在将未初始化的值传递给您的函数:

char* newCString;

....

newCString = resizeChar(newCString, stringLength);

要解决此问题,您需要为newCString提供合理的初始值,并确保resizeChar可以处理该情况。

每次循环初始化newCString会更好。这也避免了你为迷宫的每一行使用相同缓冲区的问题。

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

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

答案 1 :(得分:0)

  

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

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