1

As you can see from the images attached below, adding the second element from the top of the list create a strange behaviour for the printf function.

the function that add a list node is:

void add_QUEUEnode_top(Item a)
{
    if (head==NULL)
    {
        QUEUEinit(a);
    }
    else
    {
        QUEUEput_top(a);
    }
    return;
}

void QUEUEinit(Item a)
{
    head=(link)malloc(sizeof(link*));
    head->next=NULL;
    head->item=a;
    tail=head;
    printf("Coda iniziallizata...\n\n");

}

void QUEUEput_top(Item a)
{
    link tmp;
    tmp=(link)malloc(sizeof(link*));
    tmp->item=a;
    tmp->next=head;
    head=tmp;
    return;
}

Here the functions that handle the items:

Item fill_item()
{
    Item a;
    int i;
    for(i=0; i<DIM-1; i++)
    {
        a.stringa[i]=rand();
    }
    a.stringa[DIM-1]='\0';
    a.numero=rand();
    printf("\nOggetto generato: \n");
    print_item(a);
    return a;
}

void print_item(Item a)
{
    printf("\nStringa elemento: ");
    printf("%s", a.stringa);
    printf("\nNumero elemento:  %d\n", a.numero);
}

Here's the link to the codeblock project i'm editing. The function print_item(Item a) that call the "bugged" printf is in the item.c module, while the functions that generate a list item are inside the list.c module.

Any idea of what can cause this problem?

entering the first element of the stack

and that is what happen at the second element

PS: i'm sorry for the captures located in italian

EDIT: definition of the items:

typedef struct
{
    char stringa[DIM];
    int numero;
} Item;

Definition of the link pointer:

typedef struct QUEUEnode *link;

definition of the link structure:

struct QUEUEnode
    {
        Item item;
        link next;
    };
2
  • What are the definitions of link and Item? I'll note that the lines that look like head=(link)malloc(sizeof(link*)); are suspicious. Casting to a different type than the size you used? Actually, the cast isn't even required at all in C, but the fact that you needed to do a crazy one is a bit more telling....
    – Carl Norum
    Commented May 4, 2013 at 15:34
  • To start with, the line malloc(sizeof(link*)) does not allocate what you think it does. It allocate memory enough for a pointer (i.e. 4 or 8 bytes) which most likely will not be enough for your link structure. Commented May 4, 2013 at 15:35

2 Answers 2

4

You have several bugs - I'll try to go through and find more of them for you, but the specific problem you're asking about is related to this code:

for(i=0; i<DIM-1; i++)
{
    a.stringa[i]=rand();
}
a.stringa[DIM-1]='\0';

You're just putting a random number in each character - many of them may not be interesting or even printable characters in your character set. That's why you get the crazy output you're seeing. If you want to put random printable characters into the string, do so in a more character-set-aware way.

Some more problems:

  1. These allocation lines are wrong:

    head=(link)malloc(sizeof(link*));
    tmp=(link)malloc(sizeof(link*));
    

    They should be:

    head = malloc(sizeof(struct QUEUEnode));
    tmp = malloc(sizeof(struct QUEUEnode));
    

    That is, you should allocate enough size for an entire struct QUEUEnode, not just a pointer to one. (Or a pointer to a pointer to one, which is what you had). Hiding the pointer type inside a typedef like you do with typedef struct QUEUEnode *link; is one of those controversial style choices - I personally prefer not to, since it confuses issues like this one pretty fast.

  2. You're passing around a lot of structures by value in this program. That's fine and valid C, it's just a bit non-idiomatic. Normally people pass around pointers instead. If your structure grows to any appreciable size, performance can start to suffer badly as a result of all of the implicit memory copying going on.

8
  • oh, and if i divide the rand() by the ASCII max term? Commented May 4, 2013 at 15:40
  • No, that won't work either. There are lots of ASCII characters that you probably don't want in your string.
    – Carl Norum
    Commented May 4, 2013 at 15:41
  • well i just want something to fill that string, it's a university exercise; how do i generate a random number between the only alphanumeric ASCII characters? Commented May 4, 2013 at 15:46
  • Check an ASCII table - you need random numbers between 48 and 57 for the digits, between 65 and 90 for capital letters, and between 97 and 122 for lower case letters. I guess you could either generate those directly through some algorithm, or you could simply discard bad ones by using isalnum(). I'm not sure that's a really good solution, though.
    – Carl Norum
    Commented May 4, 2013 at 15:48
  • 1
    ... or better yet, head = malloc(sizeof *head);
    – autistic
    Commented May 4, 2013 at 16:08
2

You are allocating random text to stringa and then setting numero to a random number. When you print those things you get, well, random output. Because you have not restricted the randomisation to printable characters weird things happen. You are printing control characters. Your second screenshot would indicate that you have printed a carriage return character. I'm sure you don't want to do that!

The program is doing exactly what you asked it to do. Since you did not say what set of characters you wanted to assign to stringa from, I really could not say what your program should be. You could make it choose values in the range A to Z with this change:

a.stringa[i] = 'A' + rand() % 26;

I'll bet that there are other problems with your code, but since the main focus of the question concerned printing, I'll not look any deeper.

3
  • yes, but look at the second image what happen before the generated string! Commented May 4, 2013 at 15:42
  • @LambertoBasti, that's probably because you had a carriage return character randomly generated in that string.
    – Carl Norum
    Commented May 4, 2013 at 15:45
  • That's just the non-printing characters. Probably a CR character. Commented May 4, 2013 at 15:46

Not the answer you're looking for? Browse other questions tagged or ask your own question.