How to resolve: undefined reference to 'WinMain' - c

I am new to programming in C and I am currently trying test to see if my linked list working correctly but I keep running in to the following error whenever I use my Makefile:
C:/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/8.1.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o):crt0_c.c:(.text.startup+0x2e): undefined reference to \`WinMain'
collect2.exe: error: ld returned 1 exit status
make: *** [Makefile:2: NodeStruct] Error 1
I made sure to save all my files and to have a main function included.
All files I am working with:
NodeStruct.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "linked_list_utils.h"
int main(int argc, char *argv[]){
Node* root = NULL;
insert_end(&root, "hello");
for(Node* curr = root; curr !=NULL; curr = curr->next){
printf("%s\n", curr->x);
}
deallocate(&root);
return 0;
}
linked_list_utils.h
#ifndef LIST_H
#define LIST_H
typedef struct Node{
char *x;
struct Node* next;
}Node;
void insert_end(Node **root, char x[]);
void deallocate(Node** root);
#endif
linked_list_utils.c
#include <stdio.h>
#include <stdlib.h>
#include "linked_list_utils.h"
void insert_end(Node **root, char x[]){
Node * newNode = malloc(sizeof(Node));
if(newNode == NULL){
exit(1);
}
newNode->next = NULL;
newNode->x = x;
if(*root == NULL){
*root = newNode;
return;
}
Node* curr = *root;
while(curr->next != NULL){
curr = curr->next;
}
curr->next = newNode;
}
void deallocate(Node** root){
Node* curr = *root;
while(curr != NULL){
Node* aux = curr;
curr = curr->next;
free(aux);
}
*root = NULL;
}
Makefile
NodeStruct: NodeStruct.o linked_list_utils.o
gcc -o NodeStruct.o linked_list_utils.o
NodeStruct.o: NodeStruct.c linked_list_utils.h
gcc -c NodeStruct.c
linked_list_utils.o: linked_list_utils.c linked_list_utils.h
gcc -c linked_list_utils.c
clean:
rm -f *.o *.exe

Related

delete specific node from doubly linked list (in c) - can't delete tail

I am trying to delete just one node from a doubly linked list. My function works when the node I am deleting is the list head but not if it's another node. When I test using the list tail the program never ends.
I think it has something to do with my loop and that it's not reaching the correct node or not reconnecting the list properly.
Please let me know if you have any idea or need more info. Thanks for any help you can give.
Relevant info from header:
#include <stdio.h>
#include <stdlib.h>
typedef struct listNode{
void *data;
struct listNode *previous;
struct listNode *next;
} Node;
typedef struct listHead{
Node *head;
Node *tail;
void (*deleteData)(void *toBeDeleted);
int (*compare)(const void *first,const void *second);
void (*printData)(void *toBePrinted);
} List;
int deleteDataFromList(List *list, void *toBeDeleted);
My function:
#include <stdio.h>
#include <stdlib.h>
#include "LinkedListAPI.h"
int deleteDataFromList(List *list, void *toBeDeleted){
Node *temp = NULL;
if(list == NULL || list->head == NULL || toBeDeleted == NULL) {
return EXIT_FAILURE;
}
temp = list->head;
while(temp != NULL){
if(temp->data == toBeDeleted) {
if(temp == list->head){
list->head = temp->next;
if(list->head != NULL){
list->head->previous = NULL;
}
}
else if(temp == list->tail){
if(temp->previous){
list->tail->previous->next = NULL;
list->tail = list->tail->previous;
}
}
else {
temp->previous->next = temp->next;
temp->next->previous = temp->previous;
}
list->deleteData(temp->data);
free(temp);
temp = NULL;
return EXIT_SUCCESS;
}
}
return -1;
}

Malloc cannot allocate memory for a structure

I have the Segmentation fault (core dumped) error.
main.c
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list = NULL;
doFill(list);
printf("%s\n", list->name);
free(list);
return 0;
}
header1.h
#ifndef HEADER1_H
#define HEADER1_H
struct t_list {
char *name;
struct t_list *next;
};
void doFill(struct t_list *list);
#endif
worker.c
#include "header1.h"
#include <stdlib.h>
void doFill(struct t_list *list) {
list = (struct t_list *) malloc(sizeof(struct t_list));
char *tmp = "somename";
list->name = tmp;
list->next = NULL;
}
When I run this (gcc -g main.c worker.c -o test) I get (on the line with printf in main.c):
Segmentation fault (core dumped)
In gdb I see:
Temporary breakpoint 1, main (argc=1, argv=0x7fffffffddf8) at main.c:8
8 struct t_list *list = NULL;
(gdb) next
9 doFill(list);
(gdb) step
doFill (list=0x0) at worker.c:6
6 list = (struct t_list *) malloc(sizeof(struct t_list));
(gdb) p list
$1 = (struct t_list *) 0x0
(gdb) next
7 char *tmp = "somename";
(gdb) p list
$2 = (struct t_list *) 0x0
As you can see malloc in worker.c doesn't allocate memory for the list variable (the pointer before and after malloc points at 0x0).
If I move the code from the doFill procedure in main.c it works correctly:
main.c
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list;
list = (struct t_list *) malloc(sizeof(struct t_list));
char *tmp = "somename";
list->name = tmp;
list->next = NULL;
printf("%s\n", list->name);
free(list);
return 0;
}
$ gcc -g main.c -o test
$ ./test
somename
How is it possible? What do I do wrong?
gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1)
You aren't receiving back the new value of list. In fact, passing list in is totally useless. Better to pass in the name for this node.
typedef struct t_list List;
List *newListNode(char *name) {
List *list = malloc(sizeof(*list));
if (!list) return NULL;
list->name = strdup(name);
if (!list->name) { free(list); return NULL; }
list->next = NULL;
return list;
}
char *strdup(char *src) { // if strdup doesn't already exist.
char *dst = malloc(strlen(src) + 1);
if (!dst) return NULL;
strcpy(dst, src);
return dst;
}
To add nodes to the front of the list:
List *listAdd(List *list, char *name) {
List *newnode = newListNode(name);
if (!newnode) return NULL;
if (list) newnode->next = list;
return newnode;
}
To delete the list, remember to delete the malloced strings:
void deleteList(List *list) {
for (List *next; list; list = next) {
next = list->next;
free(list->name);
free(list);
}
}
Parameters in C are passed by copy. The changes you make to list inside of doFill() are not propagated back to main(), which means that list is always NULL in main(). Try passing a pointer to pointer instead:
#include "header1.h"
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char** argv) {
struct t_list *list = NULL;
doFill(&list);
printf("%s\n", list->name);
free(list);
return 0;
}
And then change doFill() accordingly:
#include "header1.h"
#include <stdlib.h>
void doFill(struct t_list **list) {
*list = malloc(sizeof(**list));
char *tmp = "somename";
(*list)->name = tmp;
(*list)->next = NULL;
}

Adding node to global linked list causing crash

I'm trying to add items to a linked list. The code compiles OK but when I execute the program, it crashes before adding the first node. The code looks OK to me but I must be missing something.
The code uses a global linked list which is necessary for this problem. I think my usage of it may be what is causing the crash.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkedList.h"
int main (int argc, char* argv[])
{
LinkedList *canQueue;
int ii;
createList();
FILE* f;
f = fopen(argv[1], "r");
if(f==NULL)
{
printf("Error: could not open file");
return 0;
}
for(ii = 0; ii < 10; ii++)
{
TinCan* tempCan = malloc(sizeof(TinCan));
fscanf(f, " label_%d", &tempCan->label); /*Read info from file into label field*/
insertLast(canQueue, tempCan); /*Inserts the new can into linked list*/
}
return 0;
}
LinkedList.h
typedef struct TinCan
{
int label;
} TinCan;
typedef struct Node
{
TinCan* data;
struct Node *next;
} Node;
typedef struct LinkedList
{
Node *head;
} LinkedList;
void insertLast(LinkedList* list, TinCan *newData);
void createList();
extern LinkedList* canQueue;
LinkedList.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkedList.h"
LinkedList *canQueue;
void createList() /*creates empty linked list*/
{
canQueue = malloc(sizeof(LinkedList));
canQueue->head = NULL;
}
void insertLast(LinkedList* list, TinCan *newData)
{
Node* newNode = malloc(sizeof(Node));
newNode->data = newData;
newNode->next = NULL;
if(list->head==NULL)
{
list->head=newNode;
}
else
{
Node* temp;
temp = list->head;
while(temp->next!=NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
printf("Added to end");
}
Based on your response, you need to remove this declaration from main:
LinkedList *canQueue;
It is shadowing the global canQueue, which means later on when you call insertLast:
insertLast(canQueue, tempCan);
you are operating on an unintialized pointer.

Need help traking down Run-Time Check Failure #2 - Stack around the variable 'list' was corrupted

So I am getting Run-Time Check Failure #2 - Stack around the variable 'list' was corrupted.
I have dug through the code and cant figure out where this error is occurring. Could someone look this over and tell me where I may be going wrong. To be up front this is a class assignment for a data structure and algorithm class. The teacher has accepted my code but told me I need to fix this error. I have been looking for days now and cant seem to find where it is. The only limitation on this project is that the main cannot be changed.
Thanks for your help.
Jason
list.h
typedef char Titem;
// Interface of list
typedef struct node *Tpointer;
typedef struct node {
Titem item;
Tpointer next;
Tpointer first;
} Tnode;
typedef Tpointer Tlist;
void initialize_list (Tlist *list);
void insert_to_list_end(Tlist *list, Titem data);
void print_list (Tlist *list);
void cleanup_list(Tlist *list);
list.c
#include <stdlib.h>
#include <stdio.h>
#include "list.h"
// Implementation of list (only obj is need in appl)
void initialize_list (Tlist list)
{
list->first = NULL;
list->next = NULL;
}
void cleanup_list(Tlist list)
{
Tpointer aux1, aux2;
aux1 = list->first;
while (aux1 != NULL)
{
aux2 = aux1->next;
free(aux1);
printf("\nDeleted"); //for testing purposes
aux1 = aux2;
}
initialize_list(&list);
}
void insert_to_list_end(Tlist list, Titem data)
{
Tpointer newnode;
newnode = (Tpointer) malloc(sizeof(Tnode));
newnode -> item = data;
if (list->first == NULL)
list->first = newnode; //first node
else
list->next->next = newnode; //not first node
list->next = newnode;
list->next->next = NULL;
}
void print_list (Tlist list)
{
Tpointer what;
printf("\nList 4 :");
what = list->first;
while (what != NULL)
{
printf("%c ", what->item);
printf("\nNext is %d ", what->next);
what = what->next;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "list.h"
// Application
int main (void) {
Tlist list;
initialize_list(&list);
insert_to_list_end(&list, 'a');
insert_to_list_end(&list, 'b');
insert_to_list_end(&list, 'c');
insert_to_list_end(&list, 'd');
print_list(&list);
cleanup_list(&list);
fflush(stdin); getchar();
return 0;
}
A sane compiler does not even compile your list.c -
list.c:6: error: conflicting types for 'initialize_list'
list.h:13: note: previous declaration of 'initialize_list' was here
list.c:12: error: conflicting types for 'cleanup_list'
list.h:16: note: previous declaration of 'cleanup_list' was here
list.c: In function 'cleanup_list':
list.c:24: warning: passing argument 1 of 'initialize_list' from incompatible pointer type
list.c:6: note: expected 'Tlist' but argument is of type 'struct node **'
list.c: At top level:
list.c:27: error: conflicting types for 'insert_to_list_end'
list.h:14: note: previous declaration of 'insert_to_list_end' was here
list.c:41: error: conflicting types for 'print_list'
list.h:15: note: previous declaration of 'print_list' was here
- here is a corrected version:
#include <stdlib.h>
#include <stdio.h>
#include "list.h"
void initialize_list(Tlist *list)
{
*list = NULL;
}
void cleanup_list(Tlist *list)
{
Tpointer aux1, aux2;
if (!*list) return;
aux1 = (*list)->first;
while (aux1 != NULL)
{
aux2 = aux1->next;
free(aux1);
printf("\nDeleted"); //for testing purposes
aux1 = aux2;
}
initialize_list(list);
}
void insert_to_list_end(Tlist *list, Titem data)
{
Tpointer newnode;
newnode = malloc(sizeof(Tnode));
newnode->item = data;
if (*list == NULL) //first node
newnode->first = newnode;
else //not first node
((*list)->next = newnode)->first = (*list)->first;
newnode->next = NULL;
*list = newnode;
}
void print_list(Tlist *list)
{
Tpointer what;
printf("\nList 4 :");
if (!*list) return;
what = (*list)->first;
while (what != NULL)
{
printf("%c ", what->item);
printf("\nNext is %d ", what->next);
what = what->next;
}
}

Pointer that points to return of function. Initialization from incompatible pointer type

I have some trouble with pointers. I have a function that should return the node in a linked list, the function should return the pointer to a variable. I'm confused and cannot see what I do wrong!
data.h - header file
int add(int num);
struct message *findMessage(int num);
typedef struct list_el message;
data.c - Linked list.
#include <stdio.h>
#include <stdlib.h>
struct list_el {
int num;
struct list_el *next;
};
typedef struct list_el message;
struct list_el *head, *tail;
int addNode(struct list_el *curr)
{
if(head == NULL) {
head = curr;
} else {
tail->next = curr;
}
curr->next = NULL;
return 0;
}
int add(int num)
{
message *curr;
head = NULL;
curr = (message*) malloc(sizeof(message));
curr->num = num;
addNode(curr);
return 0;
}
message *findMessage(int num)
{
message *curr;
for(curr = head; curr != NULL; curr = curr->next) {
if(curr->num == num) {
return curr;
}
}
return NULL;
}
Main.c - MAIN
#include <stdio.h>
#include "data.h"
int main(void)
{
int num = 2;
add(num);
message *curr = findMessage(num);
return 0;
}
Why not include the definition of struct list_el into the header? Otherwise main cannot work with it.

Resources