I am not sure why I am getting these errors, but the weirdest thing, I am still able to run the program and produce the results I want.
The compiler error I get is
IntelliSense: a value of type "MyStruct *" cannot be assigned to an entity of type "Mystuct_struct *"
There are 4 instances of this, but as I stated in my title, the program still seems to run fine, and displays the bin file as I want it to. And yes, I know the name of my structure is bad.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
typedef struct MyStruct_struct
{
char FlightNum[7];
char OriginAirportCode[5];
char DestAirportCode[5];
int timeStamp;
struct Mystruct_struct* next;
} MyStruct;
int main()
{
time_t time;
MyStruct * ptr;
MyStruct * head;
MyStruct * tail;
MyStruct * temp;
FILE * bin;
MyStruct myStruct;
bin = fopen("acars.bin", "rb");
ptr= (struct MyStruct_struct *) malloc (sizeof(MyStruct) );
fread(ptr,sizeof(MyStruct)-sizeof(MyStruct*),1,bin);
head = ptr; // make head point to that struct
tail = ptr; // make tail point to that struct
while (1)
{
ptr = (struct MyStruct_struct *) malloc(sizeof(MyStruct));
fread(ptr, sizeof(MyStruct) - sizeof(MyStruct*), 1, bin);
tail->next = ptr; // error here
tail = tail->next; //error here
if (feof(bin) != 0)
break;
}
tail->next = NULL;
ptr = head;
while (ptr->next != NULL)
{
printf("%s ", ptr->FlightNum);
printf("%s ", ptr->OriginAirportCode);
printf("%s ", ptr->DestAirportCode);
time = ptr->timeStamp;
printf("%s",ctime( &time));
ptr = ptr->next; // here
}
ptr = head;
while (ptr->next != NULL)
{
temp = ptr;
ptr = ptr->next; //error here
free(temp);
}
fclose(bin);
system("pause");
return 0;
}
You have a typo in your struct definition. The type for your variable next is MyStuct_Struct. Check your spelling on MyStuct_Struct. It still works because C is joiously not type safe. A pointer is a pointer is a pointer so you don't end up with memory errors.
Related
#include <stdio.h>
#include <stdlib.h>
typedef struct nodeWords
{
char * word;
int index;
struct nodeWords *left;
struct nodeWords *right;
} nodeWords;
int main(void)
{
nodeWords * node = malloc(sizeof(*node));
printf("%lu\n",sizeof(*node));
node->left = NULL;
node->right = NULL;
nodeWords * ihash = malloc(2 * sizeof(*ihash));
printf("%p \n", node->left);
//this part not working
ihash[0] = *node->left;
printf("%p\n",ihash[0]);
}
How can I assign node->left to ihash[0] and then be able to print out ihash[0], which should point to NULL?
There are two errors in your code and a few other 'minor issues' (I've commented these in the code posted below).
The first error is that you want to create an array of pointers to nodeWords, so you will need two stars in the declaration of ihash (one star will create an array of structure objects).
Second, in ihash[0] = *node->left;, you are dereferencing node twice (once with the preceding star operator, and once again with the -> operator.
The following code fixes these issues:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodeWords {
char* word;
int index;
struct nodeWords* left;
struct nodeWords* right;
} nodeWords;
int main(void)
{
nodeWords* node = malloc(sizeof(*node));
printf("%zu\n", sizeof(*node)); // Should really use "%zu" for size_t
node->left = NULL;
node->right = NULL;
nodeWords** ihash = malloc(2 * sizeof(*ihash)); // You want an array of POINTERS so you need two ** in the type!
printf("%p \n", (void*)node->left); // Pedantic: %p expects a void*
//this part not working
ihash[0] = node->left; // The "*" preceding "node" was an error: the "->" inherentlt derefernces node
// ihash[0] = (*node).left; // An alternative way of dong the same thing
printf("%p\n", (void*)ihash[0]); // Pedantic: %p expects a void*
// Don't forget to free the allocated memory...
free(ihash);
free(node);
return 0; // Always good practice to put this EXPLICIT return statement in your "main"
}
I'm trying to implement my own malloc and then test it by dumping the heap to see what I've managed to accomplish. It compiles fine but when I run it, I get the output of
head->[1:0:8]->NULL
this is a test program
after which it promptly crashes. It looks like the way I implemented my malloc, it is able to allocate the space for *this and *is, but that's all. Anyone have any ideas why this might be?
My main.c
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define MALLOC(n) my_malloc(n)
#define DUMP_HEAP() dump_heap()
void* my_malloc(int);
int main()
{
char *this = MALLOC(5);
char *is = MALLOC(3);
char *a = MALLOC(2);
char *test = MALLOC(5);
DUMP_HEAP();
strcpy(this, "this");
strcpy(is, "is");
strcpy(a, "a");
strcpy(test, "test");
strcpy(program, "program");
printf("%s %s %s %s %s\n", this, is, a, test, program);
DUMP_HEAP();
return 0;
}
My malloc.c
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <assert.h>
struct Block
{
int occ;
int size;
struct Block *prev;
struct Block *next;
};
static struct Block *head = NULL;
void *my_malloc(int size)
{
void *pointer;
pointer = (void*)sbrk(size);
if(head == NULL)
{
head = pointer;
head->occ = 1;
head->prev=NULL;
head->next=NULL;
head->size = size;
return (void*)head+sizeof(struct Block);
}
else
{
struct Block* new ;
new = pointer;
head->next = new;
new->size = size;
new->occ = 1;
new->prev = head;
new->next = NULL;
head = new;
return (void*)new+sizeof(struct Block);
}
}
void dump_heap()
{
struct Block *cur;
printf("head->");
for(cur = head; cur != NULL; cur = cur->next)
{
printf("[%d:%d:%d]->", cur->occ, (char*)cur - (char*)head, cur->size);
assert((char*)cur >= (char*)head && (char*)cur + cur->size < (char*)sbrk(0));
if(cur->next != NULL) assert(cur->next->prev == cur);
}
printf("NULL\n");
}
You aren't accounting for the size of the Block struct when asking the system for memory.
Compare this line:
pointer = (void*)sbrk(size);
to how you're attempting to account for the struct later:
return (void*)head+sizeof(struct Block);
You should be accounting for the size of the Block in the sbrk call:
pointer = (void*)sbrk(size + sizeof(struct Block));
Also, as has been pointed out, you should not do pointer arithmetic on void*. So your return statements should leave the head pointer uncasted and just add 1 to account for the block size:
return (void*)(head + 1);
Also also, upon further discussion it is clear that head is being used as the tail of the linked list. This introduces a bug in dump_heap. You may want to rename head to tail and maintain a proper head, one which only ever changes in malloc when it was previously NULL.
I created a linked list program it works perfect with ints in c.
but if change the parameter to char array, and try to do a strcpy it causes a core dump.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char mac[25];
struct node * next;
};
typedef struct node *list;
int main(void) {
lista c;
c = creoLista();
c = insert_start(c, "aa:bb:cc:dd:e1");
c = insert_start(c, "aa:bb:cc:dd:e2");
c = insert_start(c, "aa:bb:cc:dd:e3");
showList(c);
return 0;
}
list createList() {
return NULL;
}
list insert_start(list l1, char val[]) {
list n;
n =(list )malloc(sizeof(list));
strcpy(n->mac,val);
printf("ADDED: %s en ADDRESS:%p NEXT ADDRESS: %p\n", n->mac,(void *)(&n), (void *) (&n->next));
n -> next = l1;
return n;
}
void showList(list l1) {
while (l1 != NULL){
printf("Value: %s Address: %p\n",l1 -> mac,(void *) (&l1 -> next) );
l1 = l1 -> next;
}
}
Any hint on what im doing wrong and why it works with ints and not a char array
thanks
The problem is this allocation:
malloc(sizeof(list))
It shows the problem with making type-aliases of pointers as you here only allocate the size of a pointer and not the whole structure.
Your allocation is wrong, because you made it confusing by typedefing a pointer, don't do that
n = malloc(sizeof(*n));
is less error prone.
Check the return value of malloc() and there is no need for the cast, so
n = malloc(sizeof(*n));
if (n == NULL)
return NULL;
You are printing the n->next pointer's address before initializing it, change this
printf("ADDED: %s en ADDRESS:%p NEXT ADDRESS: %p\n", n->mac,(void *) (&n), (void *) (&n->next));
n->next = l1;
to
n->next = l1;
printf("ADDED: %s en ADDRESS:%p NEXT ADDRESS: %p\n", n->mac, (void *)n, (void *)n->next);
You have no function prototypes, so your compiler is using implicit function declaration, which is bad, because it will assume that all the functions return int, so you need to add these before the definition of main()
list createList();
list insert_start(list l1, char val[]);
void showList(list l1);
specially the first 2 are very important, enable compiler warnings to prevent this.
This is your code fixed:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node {
char mac[25];
struct node * next;
};
typedef struct node *list;
list insert_start(list l1, char val[]);
void showList(list l1);
int main(void) {
lista c;
c = insert_start(NULL, "aa:bb:cc:dd:e1");
c = insert_start(c, "aa:bb:cc:dd:e2");
c = insert_start(c, "aa:bb:cc:dd:e3");
showList(c);
return 0;
}
list insert_start(list l1, char val[]) {
list n;
n = malloc(sizeof(*n));
if (n == NULL)
return NULL;
strcpy(n->mac, val);
n->next = l1;
printf("ADDED: %s en ADDRESS:%p NEXT ADDRESS: %p\n", n->mac, (void *)n, (void *)n->next);
return n;
}
void showList(list l1) {
while (l1 != NULL) {
printf("Value: %s Address: %p\n", l1->mac, (void *)l1->next);
l1 = l1->next;
}
}
and you need a freeList() function too.
typedef struct node *list;
n =(list )malloc(sizeof(list));
list is pointer to struct node, malloc() should be passed the size of valid bytes to perform strcpy and list could be just 8 bytes if you are working on 64 but machine. Change malloc() allocation to size of pointer points to.
The following C code is my own way of writing a primitive linked list. It uses a struct called lnode. I know this is not the best/most efficient way to do it but my idea is this: create the base node, use an "iterator" pointer, here q, that points to that last node in the list and then add a new node.
The following code will not compile. I can't find the cause but it hates this line
struct lnode *q= malloc(sizeof(struct lnode));
Any advice on making this idea work? Thanks in advance.
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct lnode{
int value;
struct lnode *nextnode;
};
int main(){
struct lnode *startnode = malloc(sizeof(struct lnode));
startnode->value=0;
startnode->nextnode=NULL;
struct lnode *q= malloc(sizeof(struct lnode));
int i = 0;
for(i=0;i<10;i++){
struct lnode *p = malloc(sizeof(struct lnode));
p= q->nextnode;
p->value=i;
p->nextnode=NULL;
q=p;
}
return 0;
}
I would like to point out that I'm a novice. I'm using the Watcom compiler (Why? My computer is old and its all I need for these practice porgrams) The log output is
structure1.c(17): Error! E1063: Missing operand structure1.c(17):
Warning! W111: Meaningless use of an expression structure1.c(17):
Error! E1009: Expecting ';' but found 'struct' structure1.c(17):
Error! E1011: Symbol 'lnode' has not been declared structure1.c(17):
Error! E1011: Symbol 'q' has not been declared structure1.c(17):
Error! E1014: Left operand must be an 'lvalue' structure1.c(19):
I followed the advice given and changed the code the new code is this:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct lnode{
int value;
struct lnode *nextnode;
};
int main(){
struct lnode *startnode = (struct lnode *)malloc(sizeof(struct lnode));
struct lnode *q;
startnode->value=0;
startnode->nextnode=NULL;
q = malloc(sizeof(struct lnode));
doLoop(q);
return 0;
}
void doLoop(struct lnode *q){
int i = 0;
for(i=0;i<10;i++){
struct lnode *p = (struct lnode *)malloc(sizeof(struct lnode));
q->nextnode=p;
p->value=i;
p->nextnode=NULL;
printf("%i, %i\n",p->value,q->value);
q=p;
}
}
I printed the "value" values of each node in the list along with the previous value. It works except the first iteration which gives a weird output.
I suspect the compiler (Microsoft compilers for example) supports C89 standard only, which does not permit the intermingling of code and declarations. Move declaration of q to top of scope:
int main(){
struct lnode *startnode = (struct lnode *)malloc(sizeof(struct lnode));
struct lnode *q
startnode->value=0;
startnode->nextnode=NULL;
q = malloc(sizeof(struct lnode));
The code compiles - http://ideone.com/j6fGe - but the logic is wrong:
struct lnode *p = (struct lnode *)malloc(sizeof(struct lnode));
p= q->nextnode;
Besides the fact that you have a memory leak, I'm sure this is not what you intended.
q->nextnode doesn't point to a valid node, just some random memory. Which you then try to overwrite with p->value=i;.
The error messages is due to the mixing of code and declarations.
Further; You switch p and q around in the for loop.
p = q->next_node; /* here you set p to an undefined area.
* q->next_node is not malloc'd */
p->value = i; /* here you cause undefined / erronous behaviour
* Most probably a SIGSEGV */
So to sum it up, perhaps something like:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
struct lnode{
int value;
struct lnode *nextnode;
};
int main(void)
{
struct lnode *startnode;
struct lnode *p;
size_t z;
int i;
z = sizeof(struct lnode);
if ((startnode = malloc(z)) == NULL) {
fprintf(stderr, "Unable to malloc %d bytes.\n", z);
return 1;
}
/* Fill list */
p = startnode;
for (i = 0; i < 10; i++) {
if ((p->nextnode = malloc(z)) == NULL) {
fprintf(stderr, "Unable to malloc %d bytes.\n", z);
return 1;
}
p->value = i;
p = p->nextnode;
p->nextnode = NULL;
}
/* Print values */
p = startnode;
while (p->nextnode != NULL) {
printf("value: %2d\n", p->value);
p = p->nextnode;
}
/* Free */
p = startnode;
while (p != NULL) {
p = p->nextnode;
free(startnode);
startnode = p;
}
return 0;
}
So I'm trying to implement a cache in C. I have included a very slimmed down version of my code.
I keep getting this error:
prog.c: In function ‘addtolist’:
prog.c:29: warning: assignment from incompatible pointer type
prog.c:40: warning: assignment from incompatible pointer type
prog.c: In function ‘main’:
prog.c:72: warning: assignment from incompatible pointer type
from this code:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct node_
{
char * word;
int filenumber;
struct node * next;
};
typedef struct node_ * node;
node createnode()
{
node head;
head = malloc(sizeof(struct node_));
head->word = NULL;
head->next = NULL;
return head;
}
unsigned int addtolist(node head, char * word, unsigned int limit, int fileno)
{
unsigned int templimit = limit;
node temp;
node temphead = head;
while(temphead->next != NULL)
{
temphead = temphead->next;
}
temp = malloc(sizeof(struct node_));
temp->word =(char*) malloc(strlen(word)+ 1);
strcpy(temp->word, word);
temp->next = NULL;
temp->filenumber = fileno;
templimit = templimit - (strlen(word) + 1) - sizeof(struct node_)- sizeof(int);
printf("templimit is size %u\n", templimit);
if (templimit < limit && templimit > 0)
{
temphead->next = temp;
limit = limit - strlen(word) - 1 - sizeof(struct node_)- sizeof(int);
return limit;
}
else
{
free(temp->word);
free(temp);
return 0;
}
}
int main()
{
node newlist = createnode();
int i = 0;
unsigned int limit = 65;
unsigned int temp = limit;
while(temp > 0 && temp <= limit)
{
temp = addtolist(newlist, "Hello", temp, i);
i++;
printf("new limit is - \t%u\nfilenumber is - \t%d\n", temp,i);
}
node ptr = newlist;
while(ptr->next != NULL)
{
printf("node %d contains the word %s\n", ptr->filenumber, ptr->word);
ptr = ptr->next;
}
return 1;
}
I honestly can't figure out what I'm doing wrong... My logic was that, since I was typedef'ing my struct as a pointer, after I created the struct in memory, I would be able to easily step through the ensuing list. Where was the flaw in my logic?
EDIT the initial problem was fixed (I forgot an underscore in my type declaration for struct node_ next;.
Now I'm having another problem: when I try to step through the list at the bottom of my code to print out the words contained in the list, I'm basically not able to step through the list. I keep outputting:
templimit is size 43
new limit is - 43
filenumber is - 1
templimit is size 21
new limit is - 21
filenumber is - 2
templimit is size 4294967295
new limit is - 0
filenumber is - 3
node 0 contains the word (null)
node 0 contains the word Hello
For some reason, it seems that my program isn't storing my changes to my list in memory after the first iteration. Any ideas on what I'm doing wrong?
Once again, any help would be appreciated, and thanks.
Inside your structure definition you have struct node without the underscore.
you'd better have a forward declaration
typedef struct node node;
and then declare your structure
struct node {
...
node *next;
};
no need to have this underscore stuff and hiding the * in a typedef. That only makes you mix things up easily.
String literals "like this" have type const char*, not char*, because they're immutable.
Fix your declarations to have const char* and the warnings will go away.
I think the struct member 'next' has to be declared as a (node_ *) type. As written it is currently (node_ **)