#include <stdio.h>
struct node {
int data;
struct node* next;
};
typedef struct node Node;
int main() {
Node a;
a.data = 1;
if (!a.next) {
printf("hello world");
}
}
I'm writing a little linked list program to start learning c, and I'm confused as to why a.next is not null.
In short, whenever you allocate some memory in C (either explicitly or implicitly), the memory is initialized with whatever was there when the stack frame for your main function was created (ie. garbage). This is true of your int value as well (remove the a.data = 1 and print the value of a.data). C doesn't zero the memory it allocates for you (which makes C more efficient). As Anandha suggested, just set the pointer to NULL to avoid this problem.
You should initialize the pointer with NULL, the declared pointer may contain garbage value pointing to anywhere in the memory.
So a.next=NULL
Related
Hi guys I'm learning C programming. I wanted to write some codes for learning linked list topic but there is a problem. This code about creating linked list with 5 nodes, writing something into 3rd node, printing them to console.
Here is all of my codes:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
struct node{
char *data;
struct node *next;
};
typedef struct node node;
node *root;
void nodeAdd(node *n, int x)
{
node *iter;
iter=root;
for(int i=0;i<x;i++)
{
iter->next = (node*)malloc(sizeof(node));
iter->next->data="0";
iter->next->next=NULL;
iter=iter->next;
printf("Node created.\n");
}
}
void nodeWrite(node *n,char *string,int x)
{
node *temp;
temp=root;
for(int k=0;k<x;k++)
{
temp=temp->next;
}
strcpy(temp->data,string); //HERE IS ERROR
printf("\n");
printf("%s \n",temp->data);
printf("Node writed.");
}
void nodePrint(node *n)
{
while(root->next!=NULL)
printf("%s\n",root->data);
root=root->next;
}
int main(int argc, const char * argv[])
{
root = (node*)malloc(sizeof(node));
nodeAdd(root,5);
nodeWrite(root,"WTF", 3);
nodePrint(root);
return 0;
}
data is an unintialized pointer variable. Initialize with the address of a valid memory that you allocate. That will solve the problem. Now you have udnefined behavior.
What you can possibly do is
Use char array instead of using pointer.
Allocate dynamically the memory.
In case of 1.
struct node{
char data[MAXSTRINGLEN];
struct node *next;
};
In case of 2:
Initially make the pointers point to NULL. So now you can allocate to it like this
temp->data = malloc(sizeof *temp->data*MAXSTRINGLEN);
if( temp->data == NULL)
{
fprintf(stderr,"Error in malloc");
exit(1);
}
Just one point, free the allocated memory when you are done working with it.
Use of the global variable here is not really required here. You can always pass return pointers from memory and assign it to the struct node*. Or yes you can use double pointers. Use of global variable is not needed here.
Clean up code, that are redundant and not required. That makes things readable and less confusing.
The program initially is designed incorrectly and has undefined behavior..
For example the data member data of the node root was not initialized. So its output in the function nodePrint results in undefined behavior. Moreover the function itself is incorrect.
Neither function uses its parameter node *n.
In this statement
strcpy(temp->data,string);
there is an attempt to change the string literal pointed to by the data member temp->data provided that the data member was initialized (as it was pointed above the data member is not initialized for the node root). You may not change a string literal. Any attempt to modify a string literal leads to undefined behavior.
There is no need to declare the node root as a global variable.
Parameters of the function main are not used in the program. So the function should be declared like
int main( void )
So I'm doing some linked list revison and Im trying to just load a list with some numbers and then print it out. Below is my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct stack {
int data;
struct stack *next;
}*stack;
stack create_s(void){
stack s = (void*)malloc(sizeof(stack));
s->next = NULL;
return s;
}
void push_s(stack s, int data) {
while (s->next != NULL) {
s = s->next;
}
s->next = (void*)malloc(sizeof(stack));
s=s->next;
s->data = data;
s->next = NULL;
}
void print_s(stack s) {
if (s==NULL) {
return;
}
else {
while (s->next != NULL) {
printf("%d\n",s->data);
s=s->next;
}
}
}
int main (void) {
stack s = create_s();
push_s(s,2);
push_s(s,4);
push_s(s,6);
push_s(s,8);
print_s(s);
return 0;
}
My output is however:
-1853045587
2
4
6
when it should be
2
4
6
8
Is it printing the address of my struct at the beginning? Also, why is it not printing my last element?
Thanks
The code contains several errors, but the first thing that catches the eye is that your memory allocation is already obviously broken
stack s = (void*)malloc(sizeof(stack));
You defined stack as a pointer type. This means that sizeof(stack) evaluates to pointer size and the above malloc allocates enough space to store a single pointer, not enough for the entire struct stack object. The same memory allocation error is present in push_s as well.
Here's some advice
Don't hide pointer types behind typedef names. Define your stack as
typedef struct stack{
int data;
struct stack *next;
} stack;
and use stack * wherever you need a pointer. I.e. make that * visible instead of hiding it "inside" a typedef name. This will make your code easier to read.
Don't cast the result of malloc. Anyway, what is the point of casting it to void * when it is void * already???
Don't use sizeof with types unless you really really have to. Prefer to use sizeof with expressions. Learn to use the following malloc idiom
T *p = malloc(sizeof *p);
or, in your case
struct stack *s = malloc(sizeof *s);
This will allocate a memory block of appropriate size.
Also, as #WhozCraig noted in the comments, the very first node in your list is apparently supposed to serve as a "sentinel" head node (with undefined data value). In your code you never initialize the data value in that head node. Yet in your print_s function you attempt to print data value from the head node. No wonder you get garbage (-1853045587) as the first line in your output. Don't print the very first node. Skip it, if it really is supposed to serve as a sentinel.
Also, the cycle termination condition in print_s looks strange
while (s->next != NULL)
Why are you checking s->next for NULL instead of checking s itself? This condition will terminate the cycle prematurely, without attempting to print the very last node in the list. This is the reason why you don't see the last element (8) in your output.
The actual cause of the given output can be fixed by changing:
s=s->next;
s->data = data;
to
s->data = data;
s=s->next;
I'm trying to figure out how to initialize a struct if I'm passed a memory location, the situation below is what I'm trying to do, but it throws "invalid initializer" shortened to relevant code
#ifndef PAGE_ALLOC_H
#define PAGE_ALLOC_H
typedef struct listNode
{
struct listNode *prev;
struct listNode *next; // prev/next element in linked list
char * address;
} listNode;
#endif
_____________________________________________
#include "page_alloc.h"
#include <stdlib.h>
#include <stdio.h>
int main (int argc, char ** args)
{
void * memptr;
int test = posix_memalign(&memptr, 2, 128); // test is > 1, values such as 16 and 22 is this ok? It does seem to return a valid memory address though, but can't test until struct lets me initialize to it...
listNode testNode = memptr; // this throws improper initialization flag, but how else do I do tell //the struct where the eligible memory is?? Isn't that what malloc does? Return a point to acquired //memory
// Now this is what I imagine doing after telling testNode where its allocated memory
testNode ->prev = somePreviousNode; // etc.
}
I'm obviously doing something wrong but what? I'm sorry if this is a dumb question but I can't find any examples of posix_memalign nor can I find an explanation of properly initializing structs with a pointer to allocated memory. I need to dynamically add nodes because this is for a doubly linked list pointing to memory locations (used for keeping track of "pages")
Thanks for any insight!!!
testNode is an object of the structure and you are assigning a pointer (memptr) to it:
listNode testNode = memptr;
Instead create a pointer to listnode and assign the allocated memory to it:
listNode *testNode = memptr;
Note: The value of the alignment parameter should satisfy two conditions:
should be a multiple of sizeof(void*)
should be a power of 2.
For eg,
if on your machine, sizeof(void*) = 4, then the acceptable value is 4,8,16....
if on your machine, sizeof(void*) = 8, then the acceptable value is 8,16,32...
struct node
{
int info;
struct node *link;
}*start;
void main()
{
struct node*tmp,*q;
tmp=(struct node*)malloc sizeof(struct node);
}
now my first question is when we declare structure is any struct type node is created in memory?
second question is ,if yes then here i take a start pointer which is pointing to struct type node so without specifying the address of struct node to start pointer how start pointer pointing the struct type node which is created during declaration plz clear me this how internally this is happening i have lot of confusion on that
third question is initially tmp and q pointer variable all are pointing towards the same struct node
plz expalin the concept malloc and calloc how internally they create node
thx for helping me out
You can declare a structure type without declaring any variables. However, your code defines a pointer variable, start.
The variable start is initialized to 0, so it is not pointing to anything.
The variables tmp and q are not initialized at all and cannot be safely used until assigned a value. You initialize tmp in the next line; q is still uninitialized.
malloc() provides space for the pointer to point to; it does not initialize that space. The value in tmp->info is indeterminate; the value in tmp->link is indeterminate too. If you had used calloc(), then tmp->info would be zero and tmp->link would be null (on all practical systems — theoretically, there could be a system where tmp->link was not properly initialized).
Finally, note that void main() is bad. The C standard says that the return type of main() should be int. Further, unless you've got a C99 or later compiler, you should include return(0); or equivalent as the last line in main() — or a call to exit().
Am unable to run this code...
#include<cstdio>
int main()
{
struct a{
int b;
struct a *next;
};
typedef struct a no;
no *n;
n->b = 12;
n->next = NULL;
n->next->b = 12;
n->next->next = NULL;
printf("%d %d", n->b, n->next->b);
getchar();
return 0;
}
When you say:
no *n;
you get an uninitialised pointer. When you use that pointer, you get undefined behaviour.
You allocated space for a pointer to a structure, but you didn't allocate space for the actual structure. This means that you don't have a memory address for the structure you are using.
In addition, the pointer points to some random memory address because you didn't initialize it. As a result, you could be trying to read and write to memory that doesn't belong to you, which can cause your program or even your system to crash because of the undefined behavior that results.
As #Neil Butterworth said, you get an uninitialised pointer. This mean that this pointer could point to anywhere, thus giving an access violation error. The way to fix this is simple, just call malloc() before using that pointer. malloc() gives that pointer a valid and usable address, so no one will complain about that.
You're declaring a struct INSIDE a function.
Declare the struct OUTSIDE of the function.
The typedef should be declared outside the function too.
#include<cstdio>
struct a{
int b;
struct a *next;
};
typedef struct a no;
int main()
{
///... your code...
}
try something like this:
no *n = (no*)malloc(sizeof(no));
#include <cstdio>
/* declaring the struct in the function definition may be possible (I'm not sure,
actually, haha). Unless you have a GOOD reason, it's good practice to declare
structs, globals, typedefs, etc... outside the function */
typedef struct a{
int b;
struct a *next;
} no;
int main()
{
no *n;
/* Here, you have a pointer. Remember these are simply (generally) 32-bit values
defined in your stack space used to store a memory location which points to your
ACTUAL struct a! Depending on what USED to be in the stack space, this could
point ANYWHERE in memory, but usually you will find that it points to the NULL
memory location, which is just address "0". To get this to point to something,
you have to allocate empty space on your heap to store your struct... */
n = malloc(sizeof(no));
/* Now your pointer n points to an allocated 'struct a', and you can use it like
normal */
n->b = 12;
n->next = NULL;
/* You just set n->next, which is another 'no' pointer, to NULL. This means that
n->next points nowhere. So, just like above you have to malloc another instance
of the struct! */
n->next = malloc(sizeof(no));
/* NOW you can use n->next with no ill effects! */
n->next->b = 12;
n->next->next = NULL;
printf("%d %d", n->b, n->next->b);
getchar();
/* After you're done with your structs, you want to free them using the POINTERS
that reference them */
free(n->next);
free(n);
return 0;
}