-1

When I change the last parameter in the function header from char Findthis[64] to char * Findthis when debugging the Testthis=&*Look_in; assignment breaks. Look_in has a memory address and member values but Testthis is not being assigned that pointer location. Why is this happening?

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

//_DIFFERENT PART OF PROGRAM____

 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;
John
  • 13
  • 5
  • 3
    What an eyesore. This is begging for the C tag. – sbi Jan 05 '12 at 16:31
  • 2
    Please reduce your code to only what is relevant and format properly. – Mike Nakis Jan 05 '12 at 16:32
  • 1
    Testthis=new(Node); <-- that line looks like a bug; why are you allocating a new Node object only to immediately leak it on the next line? Same thing for the line CurrentHighProb=new(Node). There seems to be some confusion about how pointers work here. – Jeremy Friesner Jan 05 '12 at 16:39
  • VS2010 was complaining when I didnt have Testthis=new(Node); after the declaration. I thought it might be due to standard changes since I last programed, 1998. – John Jan 05 '12 at 16:46
  • removed the Testthis=new(Node); and converted back to passing a char *, Testthis=&*Look_in; still not functioning with Findthis as a pointer, no problem when its char Findthis[64] – John Jan 05 '12 at 16:54
  • What are you actually passing to the function? Are you passing an array of size 64? – RageD Jan 05 '12 at 17:01
  • @sbi No, indubitably C++, there's no `new` in C. – Daniel Fischer Jan 05 '12 at 17:04
  • @Daniel: Some people always write C, never mind them using `new` or `std::cout`. – sbi Jan 05 '12 at 17:17
  • When testing as char Findthis[64] I am passing "02-001 BOD" When testing as a char * Findthis I am passing user input via a cin>>Findit; and calling the function with Findit as the 3rd param – John Jan 05 '12 at 17:27
  • Could you also post the struct definition of `Node`? Perhaps if you are crashing at `...->NAME[n]`, then `NAME[n]` does not exist. – RageD Jan 05 '12 at 21:39

2 Answers2

0

Looks more like C code. Why are you using C-strings and std strings? In any case, it looks like your error is unrelated. The assignment before Testthis = &*Look_in is useless (not to mention the new call leaks memory). In this case, there is no reason to first dereference your Look_in node and then take the address. You should be able to simply change that statement to Testthis = Look_in.

However, if this is a runtime error, be certain that Look_in != NULL or is not deleted somewhere else.

It looks like you have small confusion on pointers overall; so here is a quick run-down.

Pointers point to a memory location at which some value is stored. So when you declare a pointer and assign it some memory location, you are telling that pointer where in memory to look for some item. When you dereference a valid, non-null pointer, you can get the value which that memory location holds. For instance,

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

Furthermore, memory allocation/deallocation is a different story. Stack memory (as declared above for both of those declarations) is managed by the operating system. However, heap allocation is up to you (i.e. 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;

The biggest difference between the stack and the heap is that heap memory exceeds the life of the function. For example, each function gets its own stack-frame to declare variables on. However, when the function exits, then the stack-frame is freed. Heap memory, however, can hold values which are not exclusive to a single function lifetime.

A simple example is this:

int* giveMeAnInt()
{
  int x;
  return &x;
}

In the function above, we declare a local variable, and try to return its address as a pointer to that value. However, after we return, that value is popped off the stack anyway since the function has ended. To do this properly you would have to:

int* giveMeAnInt()
{
  int* x = new int;
  return x;
}

The second example declares a variable on the heap and returns its address. But do not forget, if you use new, you must delete it later. Another quick example (using the working version of the code above i.e. example 2)

...
int * z = giveMeAnInt();
cout<< *z << endl;
delete z; // Free the memory allocated by the giveMeAnInt() function
...

That is a lot of quick information, but good luck.

EDIT

Perhaps if you are crashing at ...->NAME[n], then NAME[n] does not exist. Notice that you are effectively dereferencing Testthis at sizeof(Testthis->NAME) so the problem is not with the pointer. If you are looking for the number of characters in the string for a pointer, then you must use strlen() and not sizeof().

Here is the problem we are facing: the difference between an array and a pointer. If you declare char someArray[64], then sizeof(someArray) == 64. However, if you declare char* someArray, then sizeof(someArray) == 4 (since sizeof(char*) == 4, assuming 32-bit machine. But for now, the constant doesn't matter) and not the actual number of characters. To be safe, you should instead simply use strlen(someArray) which will work as expected for both declarations.

RageD
  • 6,693
  • 4
  • 30
  • 37
  • Thanks for the Pointers on Pointers :P But alas that still does not explain my issue here, as you can see here, http://i1140.photobucket.com/albums/n567/rand4505/cstuff/notnullpointer.jpg the List is not Null, and here, http://i1140.photobucket.com/albums/n567/rand4505/cstuff/huh.jpg the assignment is not happening. – John Jan 05 '12 at 17:13
  • That issue does not occur when Findthis is char Findthis[64]. Findthis and Testthis are not directly related, hence my original question. – John Jan 05 '12 at 17:16
  • Where are you breaking to view that information? It has to be after the assignment statement occurs of course. There is no reason that that particular statement would not work. For instance, if line 257 hasn't finished executing, it will not be assigned. – RageD Jan 05 '12 at 17:27
  • I am not breaking, the system exception happens on that assignment when Findthis is char * Findthis, no issues when Findthis is char Findthis[64]; – John Jan 05 '12 at 17:30
  • Try moving that piece of code higher (maybe at the top of your function) - is that still throwing the exception? It is odd to me that a simple pointer assignment would throw an exception (even if it was a null pointer, that line in and of itself should not throw anything). The only thing in that top segment which really could throw an exception is probably the `strcpy_s` (i.e. reading/writing to uninitialized or invalid memory) – RageD Jan 05 '12 at 17:34
  • Correction, it would let me edit the directly previous comment. I am not breaking, the system exception happens below when I try to access Testthis->NAME, while tracing backwards I found that the Testthis=Look_in; is not happening when Findthis is char * Findthis;, no issues when Findthis is char Findthis[64]; – John Jan 05 '12 at 17:40
  • Is that code located within your `while` loop? If so, try initializing `struct Node * Testthis = NULL` and leave the assignment statement. It should never enter the loop if `Testthis` is `NULL` based on your conditions. Could you update your OP to include that code since it appears to be very relevant? – RageD Jan 05 '12 at 17:42
  • This, while((Testthis->NAME[n]!='\0') causes the exception when char Findthis[64] is changed to char * Findthis in the function header. Just tried struct Node * Testthis = NULL, and it didnt help :( – John Jan 05 '12 at 18:10
  • The array is certainly null terminated? – RageD Jan 05 '12 at 18:23
  • yes, writeable[Findme.size()] = '\0'); is done right after the the user input, cin>>Findme; when using char * Findthis; writeable is then passed as the 3rd param, char * Findthis, and the arrays from Testthis are indeed null terminated. – John Jan 05 '12 at 18:31
  • I take it everyone else being as stumped as I am is not normal here? – John Jan 05 '12 at 18:50
  • Does the issue persist when trying `char Findthis[]`? – RageD Jan 05 '12 at 18:56
  • but only when passing the char * writeable – John Jan 05 '12 at 19:24
  • How is `writeable` defined/declared? Passing an array to a function gives a copy of the array to the function. Passing a pointer gives a copy of that address to the function. – RageD Jan 05 '12 at 19:28
  • Made the change to strlen(Testthis->NAME) and strlen(Findit) the first one is fine, the second causes a system access violation, trying to write protected memory. Debugger located the error on line 81 of strlen.asm – John Jan 06 '12 at 14:10
  • Any reason the cin>>Findme; would be chopping "02-001 CBOD" down to only "02-001" just noticed it during a debug. Going to try other entry methods. – John Jan 06 '12 at 14:30
  • `cin` only reads to the space, I believe. You can try `std::getline()` function. – RageD Jan 07 '12 at 22:16
  • I used Console::ReadLine(), then marshaled the variable. – John Jan 08 '12 at 02:19
0

Ok looks like the std::string to char * conversion was causing leaks.

Switched to a vector option as suggested here: How to convert a std::string to const char* or char*?

Problem went away. I'll have to trace the actual memory later but I find it odd that that string memory was placed right next to the begining of the linked-list.

Community
  • 1
  • 1
John
  • 13
  • 5