当调试char Findthis[64]
分配中断时,我将函数头中的最后一个参数从char * Findthis
更改为Testthis=&*Look_in;
。 Look_in有一个内存地址和成员值,但没有为Testthis分配该指针位置。为什么会这样?
struct Node * ProbableMatch(struct Node * Look_in, int MaxNodes,
char Findthis[64])
{
char Findit[64];
strcpy_s(Findit,64,Findthis);
struct Node * CurrentHighProb;
CurrentHighProb=new(Node);
struct Node * Testthis;
Testthis=new(Node);
Testthis=&*Look_in;
while((Testthis) || (i!=(ccounter-1)))
{ //This Testthis does not cause exception
string str1;
string str2;
n1=sizeof(Testthis->NAME);
n2=sizeof(Findit);
n=0;
while((Testthis->NAME[n]!='\0') && (n<=n1)){
//While Testthis->NAME here causes the exception
if(Testthis->NAME[n]=='-'){Testthis->NAME[n]=' ';}
n++;
}//end of while
// _ >
std::string Findme;
cout<<"Enter varible to find. Type quit to quit, case sensative."<<endl;
cin>>Findme;
char * writable = new char[Findme.size()+1];
std::copy(Findme.begin(),Findme.end(),writable);
writable[Findme.size()] = '\0';
if((Findme.compare("quit")!=0) ^ (Findme.compare("Quit")!=0) ^ (Findme.compare("QUIT")!=0)){
ProbableMatch(head,ccounter,writable);
}
delete [] writable;
// _ NODE _ ___
struct Node
{ public:
int VARID,counter,prob;
char NAME[64];
char DESCRIPTION[1024];
struct Node* next;
}node, *pNode=&node;
答案 0 :(得分:0)
看起来更像C代码。你为什么使用C字符串和std字符串?无论如何,看起来你的错误是无关的。 Testthis = &*Look_in
之前的赋值是无用的(更不用说new
调用泄漏内存)。在这种情况下,没有理由首先取消引用您的Look_in
节点,然后取出地址。您应该只需将该语句更改为Testthis = Look_in
。
但是,如果这是运行时错误,请确保Look_in != NULL
或不在其他地方删除。
看起来整个指针的混乱很小;所以这是一个快速的破败。
指针指向存储某些值的内存位置。因此,当您声明一个指针并为其指定一些内存位置时,您会告诉指针在内存中寻找某个项目。取消引用有效的非空指针时,可以获取该内存位置所包含的值。例如,
Node x[64]; // An array of 64 nodes
Node * t = x; // t points to element 0 of x. Therefore, changing values of x changes values of t and changing values of t changes values of x
此外,内存分配/释放是一个不同的故事。堆栈内存(如上所述,适用于这两种声明)由操作系统管理。但是,堆分配由您决定(即new
/ delete
)。
Node * x = new Node;
// Do stuff with your node - it is on the heap, so it is persistent until you explicitly remove it
delete x;
堆栈和堆之间的最大区别是堆内存超过了函数的生命周期。例如,每个函数都有自己的堆栈框架来声明变量。但是,当函数退出时,则释放堆栈帧。但是,堆内存可以保存不属于单个函数生存期的值。
一个简单的例子是:
int* giveMeAnInt()
{
int x;
return &x;
}
在上面的函数中,我们声明了一个 local 变量,并尝试将其地址作为指向该值的指针返回。但是,在我们返回之后,无论如何,该值都会从函数结束时弹出堆栈。要做到这一点你必须:
int* giveMeAnInt()
{
int* x = new int;
return x;
}
第二个示例在堆上声明一个变量并返回其地址。但请不要忘记,如果您使用new
,则必须稍后delete
。另一个快速示例(使用上面代码的工作版本,即示例2)
...
int * z = giveMeAnInt();
cout<< *z << endl;
delete z; // Free the memory allocated by the giveMeAnInt() function
...
这是很多快速的信息,但祝你好运。
修改强>
也许如果你在...->NAME[n]
崩溃,那么NAME[n]
就不存在了。请注意,您在Testthis
处有效解除引用sizeof(Testthis->NAME)
,因此问题不在于指针。如果要查找指针字符串中的字符数,则必须使用strlen()
而不是sizeof()
。
这是我们面临的问题:数组和指针之间的区别。如果您声明char someArray[64]
,则sizeof(someArray) == 64
。但是,如果您声明char* someArray
,那么sizeof(someArray) == 4
(从sizeof(char*) == 4
开始,假定是32位机器。但是现在,常数并不重要)而不是实际的数量字符。为了安全起见,您应该简单地使用strlen(someArray)
,这将对两个声明都有效。
答案 1 :(得分:0)
好看,std :: string to char *转换导致泄漏。
按照此处的建议切换到矢量选项:How to convert a std::string to const char* or char*?
问题消失了。我将不得不追踪实际的内存,但我觉得奇怪的是,字符串内存放在链接列表的开头旁边。