访问导致运行时错误的动态数组
Posted
技术标签:
【中文标题】访问导致运行时错误的动态数组【英文标题】:Accessing a Dynamic Array causing a runtime error 【发布时间】:2017-04-27 21:10:26 【问题描述】:我一直在搞乱动态内存,结果碰上了一堵巨大的墙。
我正在尝试创建一个程序,用户可以在其中输入任意数量的字符串,然后可以随时退出,但是在输入第二个字符串后,程序崩溃而没有给我任何特定的错误消息。
#include "stdafx.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "new"
int _tmain(int argc, _TCHAR* argv[])
//Variables
int i=0,end=0,requiresSize=1;
char ** temp;
char item[256]="a";
char ** requires;
//Initialize each element in requiers
requires = new char * [requiresSize];
for(int j=0;j<requiresSize*2;j++)
requires[j]= new char[256];
while(strcmp(item,"q-"))
end=0;
printf("Enter h- for help.\nEnter q- to quit.\n");
printf("Please enter a string\n");
gets_s(item);
if(!strcmp(item,"h-"))
printf("Enter a string to add to the list.\nEnter p- to print the list.\n");
end=1;
if(!strcmp(item,"q-"))
break;
if(!strcmp(item,"p-"))
if(requires[0]!=NULL)
for(int j=0;j<requiresSize;j++)
printf("%d. %s\n",j,requires[j]);
end=1;
while(end==0)
printf("check1:i=%d\n",i);
//if search index is larger than size of the array,reallocate the array
if(i>= requiresSize)
temp = new char * [requiresSize*2];
//Initialize each element in temp
printf("check2:temp initalized\n");
for(int j=0;j<requiresSize*2;j++)
temp[j]= new char[256];
printf("check3:temp itmes initialized\n");
for(int j =0;j<requiresSize;j++)
//for each element in requires, copy that element to temp
temp[j]=requires[j];
printf("check4:copied requires into temp\n");
delete * requires;
requires = temp;
printf("check5:deleted requires and set requires equal to temp\n");
delete temp;
requiresSize = requiresSize *2;
printf("check6:\n");
//if the index at requires is not empty, check to see if it is the same as given item
if(requires[i]!= NULL)
printf("check8:index at requires is not empty\n");
//I know the error occurs here, something to do with accessing requires[i]
if(!strcmp( item, requires[i]))
printf("check9:index at requires is the same as item\n");
//if they are the same, break out of the loop, item is already included
break;
else
printf("check10:index at requires is different\n");
//otherwise, increase the index and check again (continue loop)
i++;
break;
else
printf("check11:index at requires is null, item added\n");
//if the index is empty, add the item to the list and break out of loop
requires[i]= item;
break;
printf("check7\n");
delete requires;
return 0;
提前谢谢你。
【问题讨论】:
使用 std::string - 您的代码基本上是 C 语言,带有新的替换 malloc。 顺便说一句,您的第一个for
循环已经访问了您分配的数组超出其边界并调用 未定义的行为
#include "stdafx.h"
的存在表明您正在使用 Visual Studio。 Visual Studio 拥有市场上最好的调试器之一,即使不是最好的。我建议利用它来单步执行代码,并留意程序开始偏离预期的位置。
我正在尝试创建一个程序,用户可以在其中输入任意数量的字符串 -- std::vector<std::string>
。你写的所有代码都被那个替换了。
Example。将其与您正在尝试做的事情进行比较。
【参考方案1】:
你需要意识到像temp = requires
这样的赋值语句(在这种情况下)只是复制指针,所以temp
现在指向与requires
相同的内存位置;它不会复制该内存。
这会导致两个问题:
您正在为temp
的每个元素分配新的256 字符数组,然后重新分配temp
中的每个字符* 以指向不同的位置,从而泄漏所有内存;现在无法引用新分配的内存,因此您无法释放它。
requires
现在也指向)。
另外,如果你使用new[]
分配一个数组,你必须使用delete[]
来释放它。所以requires = new char * [requiresSize];
要求你在程序结束时使用delete [] requires;
,而不仅仅是delete requires;
。 requires
的每个 256 字符元素都相同。
因此,将temp[j]=requires[j];
替换为对strcpy(或strncpy)的适当调用。并且不要删除temp
;最后的 delete [] requires;
将处理这个问题,因为它现在指向那段内存。
【讨论】:
那么数组将如何重新分配?如果我在保存数据的同时用 new 重新分配 temp(或其指向的内存),那不会覆盖以前的数据吗? 没有。temp
只是一个指针;它的值是它指向的内存中的位置。当您为其分配一个新值时,无论是通过将其他指针的值复制给它,还是将 new/new[] 的结果分配给它,它都不会影响 temp
最初指向的内存。同样,requires = temp;
之类的语句仅使两个指针指向同一内存区域(temp
最初指向的内存;它不会释放任何内存。
那么如何扩展temp指向的已分配内存呢?
你会做你现在正在做的事情:分配新内存到temp
,复制来自required
的指针,释放required
,此时temp
就可以了下次再用。
我注释掉了`delete temp;`,这似乎一切正常。也许您可以帮助我弄清楚为什么当我尝试访问数组中的数据时,我会得到随机符号。我认为这可能不值得单独提出一个问题。以上是关于访问导致运行时错误的动态数组的主要内容,如果未能解决你的问题,请参考以下文章