为什么函数头的更改会导致指针赋值不起作用



当调试Testthis=&*Look_in;分配中断时,将函数头中的最后一个参数从char Findthis[64]更改为char * Findthis时。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]!='') && (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()] = '';
 if((Findme.compare("quit")!=0) ^ (Findme.compare("Quit")!=0) ^ (Findme.compare("QUIT")!=0)){
    ProbableMatch(head,ccounter,writable);
 }
 delete [] writable;

//_节点____

struct Node 
{   public: 
    int VARID,counter,prob;
    char NAME[64];
    char DESCRIPTION[1024];
    struct Node* next;
}node, *pNode=&node;

看起来更像C代码。为什么要使用C字符串和std字符串?无论如何,看起来您的错误是无关的。Testthis = &*Look_in之前的分配是无用的(更不用说new调用会泄漏内存)。在这种情况下,没有理由先取消引用Look_in节点,然后获取地址。您应该能够简单地将该语句更改为Testthis = Look_in

但是,如果这是一个运行时错误,请确保Look_in != NULL或未在其他地方删除。

总的来说,你在指针上似乎有一些小的困惑;所以这里有一个快速的跑步记录。

指针指向存储某个值的内存位置。因此,当您声明一个指针并为其分配某个内存位置时,您就是在告诉该指针在内存中的何处查找某个项。当您取消引用一个有效的非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;
}

在上面的函数中,我们声明了一个局部变量,并尝试将其地址作为指向该值的指针返回。然而,在我们返回之后,由于函数已经结束,该值无论如何都会从堆栈中弹出。要正确地做到这一点,你必须:

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]就不存在了。请注意,您实际上是在sizeof(Testthis->NAME)处取消引用Testthis,因此问题不在于指针。如果要查找指针字符串中的字符数,则必须使用strlen(),而不是sizeof()

这就是我们面临的问题:数组和指针之间的区别。如果您声明char someArray[64],则声明sizeof(someArray) == 64。然而,如果您声明char* someArray,那么sizeof(someArray) == 4(由于sizeof(char*) == 4,假设是32位机器。但目前,常数无关紧要),而不是实际的字符数。为了安全起见,您应该简单地使用strlen(someArray),它将按预期对两个声明都起作用。

Ok看起来像是std::string到char*的转换导致了泄漏。

切换到矢量选项,如下所示:如何将std::string转换为const char*或char*?

问题消失了。稍后我将不得不跟踪实际内存,但我觉得奇怪的是,字符串内存正好放在链表的开头。

相关内容

  • 没有找到相关文章

最新更新