0

I'm new in C and I need to create a N-branch tree, but I can't get a grip on how C works.

So far I have this:

#include <stdio.h>
#include <string.h>

typedef struct node {
    char name[50];
    char type[50]; // There are two kinds of files: directory and archive
    int number_archives;
    struct nodo *next;
    struct nodo *son;
}NODE;

void create_Archive (NODO *ptr,char name[50]){ // ptr points to the node where I'll add the son
    NODE new_Node = {name,"Archive",0,NULL,NULL};
    ptr->son = &new_Node;
}

When I try to compile I get these warnings

filetree.c:15:3: warning: initialization makes integer from pointer without a cast [enabled by default]
NODE new_node = {name,"Archive",0,NULL,NULL};

filetree.c:15:3: warning: (near initialization for ‘new_node.name[0]’) [enabled by default]
filetree.c:15:3: warning: initialization makes integer from pointer without a cast [enabled by default]
filetree.c:15:3: warning: (near initialization for ‘new_node.name[1]’) [enabled by default]
filetree.c:15:3: warning: initialization makes integer from pointer without a cast [enabled by default]

How do I make the procedure name the archive the same way it is given in arguments of the procedure?

Another error that I'm always encountering is that when I try to use the function malloc, for example:

number = (int*)malloc(sizeof(int));

I get the warning:

filetree.c:18:21: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
   number = (int*) malloc (sizeof(int));
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
tony
  • 49
  • 1
  • 10
  • First get a new keyboard or learn to proofread. Second, you need to learn the difference between a value and a pointer to a value, that is the source of all of your errors. – stark Sep 21 '14 at 00:44

4 Answers4

0

There is not equality in arrays eg

new_Node.name = name;

Use strcpy:

NODE *new_Node = malloc(sizeof(NODE)); //get memory for new node
strcpy(new_Node->value, value); //copy value to new_Node.value
strcpy(new_Node->type, "Archive"); //copy "Archive" to new_Node.type
new_Node->number_archives = 0;
new_Node->next = NULL;
new_Node->son = NULL;
0
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

    typedef struct node {
        char name[50];
        char type[50]; // There are two kinds of files: directory and archive
        int number_archives;
        struct node *next;
        struct node *son;

    }NODE;


void create_Archive (NODE *ptr,char name[50]){ // ptr points to the node where I'll add the son
    NODE* new_Node = (NODE*) malloc(sizeof(NODE));
    strcpy(new_Node->name, name);
    strcpy(new_Node->type, "Archive");
    new_Node->number_archives = 0;
    new_Node->next = new_Node->son = NULL;
    ptr->son = new_Node;

}
  • I thought that "nodo" and "NODO" should be "node" and "NODE", respectively.
  • You should include <stdlib.h> when you use the function malloc()
  • The data of local variables won't be maintained after you leave the scope, so you shouldn't return pointers to local variables.
MikeCAT
  • 73,922
  • 11
  • 45
  • 70
0

You have multiple problems in the function shown. One largely artificial problem is that you've incompletely translated nodo to node (and NODO to NODE); that's easily fixed, and leaves you with:

void create_Archive(NODE *ptr, char name[50])
{
    NODE new_Node = { name, "Archive", 0, NULL, NULL };
    ptr->son = &new_Node;
}

Problem 1 is being vociferously reported by the compiler; you can't initialize an array like new_Node.name by copying a pointer like name to it. You need to use strcpy() for that.

The second problem is that you create a local variable, then store a pointer to it in the ptr->son, but when the function exits, the pointer becomes invalid and the space used for new_Node will soon be used for other purposes. This is simply undefined behaviour.

You do need to use dynamic memory allocation to resolve this. Whenever you use malloc() or one of its relatives, you must include <stdlib.h> — that is a sine qua non. That will resolve the other problem you're reporting. Putting this together, you end up with:

#include <stdlib.h>

void create_Archive(NODE *ptr, char name[50])
{
    NODE *new_Node = (NODE *)malloc(sizeof(*new_Node));
    if (new_Node != NULL)
    {
        *new_Node = (NODE){ "", "Archive", 0, NULL, NULL };
        strcpy(new_Node.name, name);
    }
    ptr->son = new_Node;
}

This uses a C99 'compound literal' (that's the (NODE){ … } notation). If you don't want to use that, then you'll need to use something more like:

void create_Archive(NODE *ptr, char name[50])
{
    NODE *new_Node = (NODE *)malloc(sizeof(*new_Node));
    if (new_Node != NULL)
    {
        strcpy(new_Node->name, name);
        strcpy(new_Node->type, "Archive");
        new_Node->number_archives = 0
        new_Node->next = NULL;
        new_Node->sone = NULL;
    }
    ptr->son = new_Node;
}

When using malloc() or related functions, it is important to check the returned value, and do not dereference the pointer if it is NULL.

I observe that the notation with underscore separating words and initial capitals on subsequent words is an unusual hybrid notation. The names createArchive and create_archive are the normal conventions. It does no harm except that it is not normally used.

There are those who will excoriate me (and you) for casting the result of malloc() as shown. Given that you are not reliably including <stdlib.h> in your code, you should heed those people until you compile your code with options such that the omission will prevent your code from compiling. I can use it because I always compile with options such as:

gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
    -Wold-style-definition -Werror -c node.c

and if I omitted <stdlib.h>, there'd be a compilation error. Until you can confidently say you always compile with equivalent options, you should not cast the result from malloc() — and maybe you won't bother to learn the old-style idiom that was necessary in the days before ANSI C (C89), or that is still necessary if your code is intended to be compilable by a C++ compiler. Renaming the file to node.cpp and compiling with G++ produces no errors or warnings either:

g++ -O3 -g -std=c++11 -Wall -Wextra -Werror -c node.cpp

That would not compile if the cast were omitted. However, I am making no pretense whatsoever that the code is good C++; it is not — it is just written in the common subset of C and C++.

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
-1

Another error that I'm always encountering is that when I try to use the function malloc(), for example:

number = (int*)malloc(sizeof(int));

I get the warning:

filetree.c:18:21: warning: incompatible implicit declaration of built-in function ‘malloc’ [enabled by default]
   number = (int*) malloc (sizeof(int));

You should include <stdlib.h> when you use the function malloc().

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
MikeCAT
  • 73,922
  • 11
  • 45
  • 70