I am trying to figure out how the newNode addresses change each iteration of appendNode. When I convert the addresses from hexadecimal to decimal I get the values 14683824, 14683848, 14685096. While the first two addresses seem to increase by 24 the third address increases by 1248. I can't figure out why this is occurring.
//Main Program
#include <iostream>
#include "numberList.h"
using namespace std;
int main()
{
numberList list;
list.appendNode(2.5);
list.appendNode(3.4);
list.appendNode(5.6);
// list.displayList();
return 0;
}
//append.cpp
#include <iostream>
#include "numberList.h"
using namespace std;
void numberList ::appendNode(double num)
{
listNode *newNode;
listNode *nodePtr;
newNode = new listNode;
newNode->value = num;
newNode->next = nullptr;
cout << newNode << endl; //The addresses of the newNode dont have even
intervals
if(!head)
{
head = newNode;
}
else
{
nodePtr = head;
while(nodePtr->next)
{
nodePtr = nodePtr->next;
}
}
}
//numberList.h
#ifndef APPENDNODE_NUMBERLIST_H
#define APPENDNODE_NUMBERLIST_H
class numberList
{
private:
struct listNode
{
double value;
struct listNode *next;
};
listNode *head;
public:
numberList()
{
head = nullptr;
}
//~numberList();
void appendNode(double);
void displayList() const;
void insertNode(double);
void deleteNode(double);
};
#endif //APPENDNODE_NUMBERLIST_H
Output:
0xe00eb0
0xe00ec8
0xe013a8
The standard doesn't give you any guarantees about the location of memory you allocate. new could give you locations that are right next to each other, but it'd also be allowed to give you locations on a completely random basis. What specifically you end up with depends on
The algorithm used for allocation by new
The pattern of previous allocations
So why did it happen this time? In general, it makes sense for successive allocations to end up close together because that decreases the chance of a cache miss, but new has no obligation to do that. In fact, because new occasionally has to request memory from the operating system, and because new has to use a bit of memory to keep track of what's been allocated, it's not possible to guarantee that all allocations happen at regular intervals.
Related
I stumbled across this question in an old textbook I bought ages ago, whilst strictly speaking it is not too difficult, I could not find a post here that simply answered this one question. As such I thought "Hey perhaps someone starting out might be confused about this", and so I put together the following code:
#include <iostream>
using namespace std;
// Structures
struct charNode {
char Node;
charNode *next;
};
// Functions
charNode* getCharNode(char c) {
return ; //<----- Return Node Here
}
What this needs is to be put in a class or else you must have a global variable that points to the head of that singly linked list.
An example class could look like this:
#include <iostream>
class singly_linked_list {
struct charNode {
char Node;
charNode *next;
};
public:
// find the charNode with the value `c`:
charNode* getCharNode(char c) {
for(charNode* curr = head; curr != nullptr; curr = curr->next) {
if(curr->Node == c) return curr;
}
return nullptr;
}
// add member functions to add/remove charNode's from the list etc
// and implement one of "the rule of 3" or "the rule of 5"
private:
charNode* head = nullptr;
};
You can implement getCharNode() function like in following code. I used this function for an example of creating singly linked list of chars. Also created extra function print_list() which outputs linked list to console.
Notice that I did only allocation of nodes (new operator), and didn't do deallocation (delete), I left this task for you to do, if you care about memory leaks.
Try it online!
#include <iostream>
// Structures
struct charNode {
charNode(char value, charNode * _next = nullptr)
: Node(value), next(_next) {}
char Node;
charNode *next;
};
// Functions
charNode* getCharNode(char c, charNode * next = nullptr) {
return new charNode(c, next);
}
void print_list(charNode const * node) {
if (!node)
return;
std::cout << node->Node << " ";
print_list(node->next);
}
int main() {
charNode * list = getCharNode('a',
getCharNode('b', getCharNode('c')));
print_list(list);
}
Output:
a b c
Can you help me understand why this code randomly results in memory access violation? Goal is to generate a binary search tree from sorted list.
Stepping through code I noticed a behavior where node pointer randomly changes when a recursive calls to fromSortedArray() function is returned. To give you a contex I am compiling this app using XCODE.
#include <iostream>
using namespace std;
class BST{
private:
struct Node {
int val;
struct Node *left, *right;
} *root;
public:
BST(){
this->root = NULL;
}
struct Node * fromSortedArray(int data[], int left, int right){
if(left>right) return NULL;
int m = left+(right -left)/2;
struct Node *node = (struct Node *) malloc(sizeof(struct Node*));
node->val = data[m];
node->left = this->fromSortedArray(data, left, m-1);
node->right = this->fromSortedArray(data, m+1, right);
return node;
}
void fromSortedArray(int data[], int n){
this->root = fromSortedArray(data, 0, n-1);
}
void deleteTree(struct Node *root){
if(root==NULL) return;
deleteTree(root->left);
deleteTree(root->right);
delete root;
}
void deleteTree(){
this->deleteTree(this->root);
}
void traverse(struct Node *root){
if(root == NULL) return;
if(root->left!=NULL)traverse(root->left);
printf("%d ", root->val);
if(root->right!=NULL)traverse(root->right);
}
void traverse(){
this->traverse(this->root);
}
~BST(){
deleteTree();
}
};
int main(int argc, char * argv[]){
BST tree;
int data[] = {2,3,5,6,7,9};
tree.fromSortedArray(data, 6);
tree.traverse();
cout << "\n";
return 0;
}
I think this line is wrong.
struct Node *node = (struct Node *) malloc(sizeof(struct Node *));
should be
sizeof(struct Node) becacuse you want to apply memory for Node not Node*
The Nodes are being malloced. One cannot combine malloc and delete. malloc must be matched with free and new must be matched with delete.
Avoid malloc. It gets you bytes of memory and nothing more, and you can easily miscalculate the number of bytes required. malloc should only be used in C++ in rare edge cases. More reading on the topic: In what cases do I use malloc vs new?
Use new instead of malloc and if at all possible, don't use new either. Use an Automatic variable, a library container, or a smart pointer instead.
This is a tree structure and, opinion here, so long as you observe the Rules of Three and Five you can get away with raw, stupid pointers because it's the the tree structure's job to handle the management of the nodes. That said, play around a bit with std::unique_ptr and std::make_unique when you get a chance. They can make your life easier.
Sticking with raw pointers for now, replace
struct Node *node = (struct Node *) malloc(sizeof(struct Node*));
with
Node *node = new Node;
I have some experience with Java and Eclipse, but I'm new to C++, and trying to teach myself. I apologize if this is a simple question, or one that has already been asked (though I looked around for a while.) I'm on a Windows 8.
I'm trying to make a sorted linked list (which is relatively unimportant.) I get:
Info: Nothing to build for Working.
Here's my code:
/*
* SortedList class
*/
#include <string>
#include <fstream>
#include<iostream>
#include "SortedList.h"
using namespace std;
//the ListNode Structure
struct ListNode {
string data;
ListNode *next;
};
//the head of the linked list and the pointer nodes
ListNode head;
ListNode *prev, *current;
// insert a string into the list in alphabetical order
//now adds a string to the list and counts the size of the list
int Insert(string s){
//make the new node
ListNode temp;
temp.data = s;
//the node to traverse the list
prev = &head;
current = head.next;
int c = 0;
//traverse the list, then insert the string
while(current != NULL){
prev = current;
current = current->next;
c++;
}
//insert temp into the list
temp.next = prev->next;
prev->next = &temp;
return c;
}
//Return the number of times a given string occurs in the list.
int Lookup(string s){
return 0;
}
//prints the elements of the list to ostream
void Print(ostream &output){
}
int main( int argc, char ** argv ) {
cout << Insert("a") << endl;
cout << Insert("b") << endl;
cout << Insert("d") << endl;
}
And here's my header:
using namespace std;
#ifndef SORTEDLIST_H_
#define SORTEDLIST_H_
class SortedList {
public:
// constructor
SortedList();
// modifiers
int Insert(string s);
// other operations
int Lookup(string s) const;
void Print(ostream &output) const;
private:
struct ListNode {
string data;
ListNode *next;
};
// pointer to the first node of the list
ListNode head;
ListNode *prev, *current;
};
#endif /* SORTEDLIST_H_ */
Any help would be greatly appreciated.
Why don't you use std::deque (in header deque)? It probably has all the functionality you are seeking, it is fully tested and optimised. If you need a deque with a bit more of functionality, create a class that inherit from it and add the functions you need. Have a look to http://en.cppreference.com/w/cpp/containe and pick up the container that best suits your needs.
As a general advise, if something you need is already available in some good and stable library (STL, boost, GSL, Armadillo or similar), much better use it rather than to write+debug+optimise it yourself from scratch. As a general advise, focus your efforts on the code that is unique to your application, and reuse what has already be done (BUT only if it has been well tested, do not use crappy half cooked libraries).
How do you allocate memory for an link list when passing its reference instead of its pointer?
For example:
struct node {
string info;
node *next;
};
void add(node &aNode){
//if I use
node *newNode;
newNode = new node;
aNode.next = newNode; //aNode.next = newNode; doesn't work either
//allocating on heap seems to give segmentation error.
}
int main() {
node *aNode;
aNode = new node;
add (aNode);
}
Compiler error: error: invalid initialization of reference of type ‘node&’ from expr
alternatively if I use
int main() {
node aNode;
add (aNode);
add (aNode);
aNode.next->next->info = "abc";
string a = aNode.next->next->info;
}
This give segmentation fault.
So is it possible to allocate for an linked list just with its reference? (this is C++)
It should be
node * newNode = new node;
aNode.next = newNode
You have to take care of deletion manually, e.g. check if aNode.next isn't already occupied (and delete if it is).
Further, the add function signature should read:
void add(node & aNode) { ... }
By the way, the STL comes with a nice <forward_list> ;-)
It's hard to tell what you're actually asking, but going by the question title perhaps you have in mind a node structure like this:
struct Node {
Node & next;
/* payload data */
Node(Node & n) : next(n) /* ... */ { }
};
Such a node would store its successor "by reference"; but you would have to initialize it with an existing node! (There is no such thing as a "null" reference.) By the Poultry-Oval Impasse, you cannot do this.
Alright, while you continue to refuse to post your full code, here is my almost literal copy/paste of your code which works fine with me:
Update: I'm adding a feature to add a node at the end, which you might want.
#include <string>
struct node {
std::string info;
node *next;
node(std::string i = "") : info(i), next(NULL) { }
};
void add(node &aNode)
{
node *newNode;
newNode = new node;
aNode.next = newNode;
}
void add_at_end(node &aNode, std::string value = "")
{
node *newNode, *n = &aNode;
while (n->next) n = n->next; // move to the end
newNode = new node(value);
n->next = newNode;
}
int main()
{
node aNode, bNode;
add(aNode);
add_at_end(bNode, "Hello");
add_at_end(bNode, "World");
add_at_end(bNode, "!");
}
Compile with g++ -o prog prog.cpp -W -Wall -pedantic.
Finally, here's the STL way of achieving the same thing:
#include <forward_list>
#include <string>
int main() {
std::forward_list<std::string> bList;
bList.push_front("Hello");
bList.push_front("World");
bList.push_front("!");
}
In your second variant of main(), you are calling add(aNode) twice. But you're providing it the same parameter each time. So although you're creating two new node objects, one of them is lost forever (a memory leak). And aNode.next ends up pointing to the other one. aNode.next->next is not a valid pointer, hence the seg-fault when you try to access something through it.
Depending on what you want to achieve, you could try this:
node aNode;
add(aNode); // Basically does: aNode.next = new node;
add(*aNode.next); // Basically does: aNode.next->next = new node;
There are better ways of doing linked-lists, but this would at least avoid the seg-fault.
Try
int main() {
node *aNode;
aNode = new node;
add (*aNode);
}
You have to pass reference to object, not a pointer.
I checked your code and I didn't get segmentation fault when allocating on stack: http://ideone.com/gTRIG.
My proposition:
#include <string>
using namespace std;
struct node {
string info;
node *next;
node(string str): info(str), next(NULL) {}
~node() { if(next != NULL) delete next; }
node *add(string info){
node *newNode = new node(info);
return aNode.next = newNode;
}
};
int main(){
node rootNode("My rootnode");
node *nxt = rootNode.add("Next node");
nxt->add("Last node");
// No need to call delete, because destructor will clear heap
}
Hey guys,
I'm studying for a midterm right now and am working on trying to create a simple program using single linked list. All I want it to do is insert "1", "2", "3", "4" into the list and print it out. Please take a look at the following code:
#include <iostream>
#include <string>
using namespace std;
class node{
public:
node(int data);
friend class slist;
private:
int data;
node *next;
};
node::node(int data){
data = data;
next = NULL;
}
class slist{
public:
slist(){
head = NULL;
}
void insert(int item);
void output();
private:
node* head;
};
void slist::insert(int item){
node* newnode = new node(item);
if(head == NULL)
{
head = newnode;
}
else
{
newnode->next = head;
head = newnode;
}
}
void slist::output(){
node* p = head;
while (p->next != NULL){
cout << p->data << " ";
p = p->next;
}
cout << p->data << " ";
}
int main(){
slist FINAL;
FINAL.insert(1);
FINAL.insert(2);
FINAL.insert(3);
FINAL.insert(4);
FINAL.output();
return 0;
}
It compiles fine, but it prints out (I'm guessing) pointers instead of the actual numbers. Can anyone tell me why?
Thanks so much!
There is a bug in the node constructor. The argument data conflicts with the memeber variable named data. This should fix it:
node::node(int data){
this->data = data;
next = NULL;
}
The better option is to rename the argument to something else. Also consider using an initialization list:
node::node(int d) : data(d), next(NULL) { }
node::node(int data) {
data = data;
next = NULL;
}
The line data = data is a problem for you. Rename the parameter to be different from the member. This ought to give you a series of garbage values (not pointers) for the member variable data.
Note: this is one of the reasons for naming convention distinguishing members variables, being it traling or leading _, m_ or wherever the balance is b/w info and aesthetics.
Well, I think both instances of data in
data = data;
are local; so the data member of node never gets anything assigned to it. What's getting printed are undefined values, not addresses. That's in any case stylistically terrible; there are many conventions here but a good one is _data for the class member, and data for the function argument. Make that simple change and see if that doesn't clear up your problem.