how to create a dummy node and set it to NULL? - adt

I am trying to create dummy node in my createList() function, however everytime I run the program, it results in a segmentation fault. Here is my code so far for createList();
node*createList()
{
node*dummyNode;
dummyNode->next = NULL;
return dummyNode;
}
any help would be appreciated.

This line
node*dummyNode;
creates a local variable that lives only inside your function createList. After the method is left, the variable is freed. I assume you use C or C++, thus you have to allocate memory with malloc
node*dummyNode = malloc(sizeof(node));

Related

memory leak delete linked list node

Newbie question. Suppose I have a C++11 linked list implementation with
template <typename X> struct Node {
X value;
Node* next;
Node(X x) {
this->value = x;
this->next = nullptr;
}
};
and later in the code I create a pointer variable
X x = something;
Node<X>* node = new Node(x);
and still later I do
delete node;
Is the x stored within node destructed when this statement is executed?
You may tell me I should use std::list instead of writing my own, but right
now I'm just trying to educate myself on pointers.
Since you did not provide a custom desctructor the compiler will generate the default one for you, which (by default) call destructors on its elements.
Now, the answer to your question really depends on what your x is :) If it is an object that has a destructor (like std::string) - it will be properly destroyed. But if it is a "naked pointer" (like int *) - it will not get destroyed and will cause a memory leak.
N.B. You create your x on a stack so I really-really-really hope that X provides proper copy semantics, otherwise you may end up with an invalid object stored in your node!

reassigning a new object to a static type object in C++

I have the following piece of code that I have a question about.
f()
{
static V v(10,0);//first argument is size and the second is init val for each element
...
v = V(5,0);
}
Does the previously allocated V(10,0) get destroyed automatically when I call V(5,0) and assign it to v in the second line ? Or do I have to destroy it ?
Since v is static, is the object V(5,0) retained across function calls ?
Does the previously allocated V(10,0) get destroyed automatically when I call V(5,0) and assign it to v in the second line ? Or do I have to destroy it ?
No. The object lives for the life of the application. Its state is changed by the assignment operation.
The object gets destroyed automatically when the application is terminated. You don't have to destroy it. If you try to destroy it, your program will have undefined behavior.
PS You can use better names than v and V to make the code and the discussion more meaningful.

passing pointers

I have this declared above:
char PandaImage[] = "images/panda.png";
SDL_Texture* PandaTexture = nullptr;
I have a function to create textures:
void LoadMedia( SDL_Texture *ThisTexture, char *Image )
{
SDL_Surface* TempSurface = nullptr;
.......................
ThisTexture = SDL_CreateTextureFromSurface( gRenderer, TempSurface );
I call it as:
LoadMedia( PandaTexture, PandaImage );
It builds, logs the image loaded and texture created, but no image
If I hard change the line ( use Panda directly instead of This ):
PandaTexture = SDL_CreateTextureFromSurface( gRenderer, TempSurface );
My image is there.
I have always had trouble with & * and passing.
Is there a good, simple help for me?
Thanks for your kind help - back to Google for now
In short, I think you could solve your problem by changing the function to:
void LoadMedia( SDL_Texture** thisTexture, char* Image)
{
...
(*thisTexture) = SDL_CreateTextureFromSurface( gRenderer, TempSurface);
}
And by calling the function using:
LoadMedia( &PandaTexture, PandaImage);
An explanation:
Variables and Pointers
A variable is used to store data (a primitive or a class instance). For example:
int a = 10;
stores an integer in memory. This means, that symbol 'a' now represents number 10, which is stored somewhere in your computer's memory as 4 bytes.
A pointer is used to store an address (this address points towards a variable). For example:
int* a_address = 1234;
says that there is an integer stored at address 1234 in your computer's memory. A pointer always takes up the same amount of space (4 bytes on a 32 bit machine and 8 bytes on a 64 bit machine), as it simply stores an address.
Getting the Address of a Variable [&]
You will rarely ever set the address of a pointer yourself. Often, pointers are the result of a "new" call. Using "new" reserves memory to store an instance of the class you want to create, and returns the address of the object. In essence, it says: "I created an object for you, and you can find it at this location in your memory".
Alternatively, when you have a normal variable (primitive of class instance), you can find its address by using the & character. For example:
int a = 10;
int* a_address = &a;
says: "store the location of variable a in pointer a_address. Why would you do this? Say you have a very large instance (for example an SDL_Texture consisting of many, many pixels) and you want to pass it to a function (or pass it back outside of the function). If you were to pass it to the function as SDL_Texture thisTexture, you are copying the entire object (a so-called pass by value). This is time consuming. Alternatively, you could simply pass the address to the function, as an SDL_Texture * thisTexture. This is a so called pass by reference, and it is much faster as you can imagine.
Getting the Variable at an Address [*]
Obviously, if you have an address, you also need a way to get the actual variable at that address. This is done using the * character. It is called "dereferencing". For example:
int a = 10;
int* a_address = &a;
int b = (*a_address);
This last line says: "Give me the variable, stored at address a_address, and put it in b".
Function Parameters Going Out-of-scope
When a function ends, its local variables (including parameters) go out-of-scope. This means that their memory is freed (for variables, not for dynamically allocated objects stored as pointers!). Their values will be forgotten. In your case, you are passing an SDL_Texture * as a parameter. This means, a copy is made of the address stored in PandaTexture. This address is copied over to thisTexture. You then write the return value of SDL_CreateTextureFromSurface to thisTexture. Next the function ends, and thisTexture goes out-of-scope. As a result, the location of your SDL_Texture (the SDL_Texture * pointer) is lost forever. You actually want to store the address to pointer PandaTexture, but as you can see, the address is only written to thisTexture.
Solution: How to Fix your Function
We can fix this by passing a pointer, to your pointer called PandaTexture. A "pointer to a pointer" is written as:
SDL_Surface** thisTexture;
We want to pass the address of pointer PandaTexture to this. This way, we can write to PandaTexture from inside your method! After all, we know where PandaTexture stores its pointer in memory, allowing us to change it. To actually put the address of PandaTexture in it, we need to use the & character in the function call as such:
LoadMedia(&PandaTexture, PandaImage);
Next, inside of our function, we want to change the value of PandaTexture. However, we were passed &PandaTexture and not PandaTexture itself. To write the value of &PandaTexture (the address where our texture will be stored), we need dereferencing, as such:
(*thisTexture) = SDL_CreateTextureFromSurface(gRenderer, TempSurface);
This works because: "thisTexture is a pointer to a pointer to an SDL_Texture (aka an SDL_Texture**). By dereferencing it, we obtain a pointer to an SDL_Texture (aka an SDL_Texture*). Here we can store the return value of the SDL_CreateTextureFromSurface function.
Why do we not run into out-of-scope issues here? Parameter thisTexture will still go out of scope, and its value will be forgotten. But! We didn't write to thisTexture, instead we wrote our SDL_Texture * pointer to the address that thisTexture points to! This bit of memory is not cleared due to scoping, so we can view the results from outside the function!
In summary, you can solve your problem using a pointer to a pointer. I hope the above clears up the concepts of pointers, variables, addresses and dereferencing a bit!

Access violation reading location using Cudd

I am trying to implement an algorithm in Visual C using Cudd package. I have to use a function recursively. But it keeps throwing an error at one particular line. Error is Access violation reading location 0x00594a5ct. And it is coming against the usage of temp_bdd_result. I am unable to figure out why is this happening because both values used in temp_bdd_result-bdd_node & bdd_result are containing values. So why are they not accessible. Or this error points to some thing else that I am not able to see. Please Help.
DdNode* Path_Function_Construct(DdManager *manager,int matrix[3][3],int source)
{
DdNode *bdd_node,*bdd_result,*e,*temp_bdd_node,*temp_bdd_result;
if (source>=rows)
return Cudd_ReadOne(manager);
else
{
bdd_result=Cudd_ReadZero(manager);
Cudd_Ref(bdd_result);
for (int j=0;j<columns;j++)
{
if (matrix[source][j]==1)
{
//Declaring temp variables
//This means that an edge exists between source and node in consideration
e=Cudd_bddNewVar(manager);
Cudd_Ref(e);
//Removing redundant nodes
int new_matrix[3][3];
for(int l=0;l<rows;l++)
for(int m=0;m<columns;m++)
new_matrix[l][m]=matrix[l][m];
for(int i=0;i<rows;i++)
new_matrix[i][j]=0;
//find path function using that node as a source
temp_bdd_node=Path_Function_Construct(manager,new_matrix,j+1);
Cudd_Ref(temp_bdd_node);
bdd_node=Cudd_bddAnd(manager,e,temp_bdd_node);
Cudd_Ref(bdd_node);
temp_bdd_result=Cudd_bddIthVar(manager,4);
temp_bdd_result=Cudd_bddAnd(manager,bdd_result,bdd_node); //this is where error is coming
Cudd_Ref(temp_bdd_result);
Cudd_RecursiveDeref(manager,bdd_result);
bdd_result=temp_bdd_result;
Cudd_Ref(bdd_result);
Cudd_RecursiveDeref(manager,temp_bdd_node);
Cudd_RecursiveDeref(manager,temp_bdd_result);
Cudd_RecursiveDeref(manager,bdd_node);
Cudd_RecursiveDeref(manager,e);
} // end of if (matrix[source][j]==1)
}// end of for loop
return (bdd_result);
}
}
Cudd_RecursiveDeref() recursively deletes a node and all its child. So whenever bdd_node was dereferenced using Cudd_RecursiveDeref() bdd_result was also removed and its value was not returned by the function. So to retain the value for returning use Cudd_Deref() instead. It just decreases the reference count without deleting its child nodes.

XercesDOMParser* and DOMDocument* going out of scope before a DOMElement*

Short Version: Is it safe for a XercesDOMParser* and DOMDocument* to go out of scope before a DOMElement* that they were used to create does?
Long version:
In the code snippet below I create a local XercesDOMParser* and DOMDocument* in order to get the root element of the document and store it in a member DOMElement* variable. The XercesDOMParser* and DOMDocument* both go out of scope at the end of the constructor, but the DOMElement* lives on as a member variable. Is this ok? So far it seems to work but I am nervous that I may have problems later.
JNIRequest::JNIRequest(JNIEnv *env, jobject obj, jstring input)
{
char *szInputXML = (char*) env->GetStringUTFChars(input, NULL);
XMLPlatformUtils::Initialize();
XercesDOMParser* pParser = new XercesDOMParser();
XMLByte* xmlByteInput = (XMLByte*) szInputXML;
xercesc::MemBufInputSource source(xmlByteInput, strlen(szInputXML), "BufferID");
pParser->parse(source);
DOMDocument* pDocument = pParser->getDocument();
/* This next variable is a DOMElement* */
this->_pRootElement = pDocument->getDocumentElement();
}
Your code snippet looks like it is creating some memory leaks. I'm afraid this is also the reason why the code seems to "work" for the moment.
In general the Xerces parser owns the document tree. Please take a look at AbstractDOMParser::adoptDocument() to transfer the ownership away from the parser. This means for your code example, if you would correctly release the parser, the document is also deleted making your pointer to the DOMElement invalid.
The solution would be to call adoptDocument() and save the pointer to the Document Element afterwards. Please note that you need to release the node tree (on closing the application?) and that the tree could consume a lot of memory depending on the size of the XML ...
Hope this helps

Resources