1

I'm trying to use printf to print out an array of chars inside a pointer called point_person, When I'm using it to return the first name of an user it prints out a lot of garbage and then finally the name.

The code looks kind of like this:

    person dequeue_person;
    person *point_person = &dequeue_person;
    get_person(point_person, 9);
    printf("%s", point_person->first_name);

person is a typedef struct containing 3 char variables: first_name[64], last_name[64], pes_nbr[64].

The output looks like this:

F÷rnamn: John ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠ ╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠╠John

What causes this and how do I avoid this in the future?

EDIT: The code populating first_name looks like this:

void get_person(person *pers, int index)
{
    person per_son;

    strcpy(per_son.first_name, queue[(index+head)%QUEUE_MAX_SIZE].first_name);
    strcpy(per_son.last_name, queue[(index+head)%QUEUE_MAX_SIZE].last_name);
    strcpy(per_son.pers_nbr, queue[(index+head)%QUEUE_MAX_SIZE].pers_nbr);

    pers = &per_son;
    printf("Förnamn: %s\n", per_son.first_name);
}

EDIT 2: Figured it out by myself. I had to edit the get_person function and remove the per_son struct and change the strcpy to pers instead of pers_son.

Kraffs
  • 533
  • 2
  • 7
  • 22
  • 1
    In the posted code `first_name` is never populated. Can you post the code that populates it? – hmjd Nov 11 '12 at 22:21
  • ╠ is 0xCC in codepage 437, and [MSVC fills 0xCC to uninitialized memory to help debugging](https://stackoverflow.com/q/370195/995714). That means you've accessed uninitialized memory. You can find tons of questions about ╠ and 0xCC here on SO – phuclv Aug 18 '18 at 10:53

3 Answers3

1

You should use passed person - not local person:

void get_person(person *pers, int index)
{
    // NOT NEEDED: person per_son;

    strcpy(pers->first_name, queue[(index+head)%QUEUE_MAX_SIZE].first_name);
    strcpy(pers->last_name, queue[(index+head)%QUEUE_MAX_SIZE].last_name);
    strcpy(pers->pers_nbr, queue[(index+head)%QUEUE_MAX_SIZE].pers_nbr);

    // WRONG: pers = &per_son;
    printf("Förnamn: %s\n", pers->first_name);
}
PiotrNycz
  • 23,099
  • 7
  • 66
  • 112
0

person dequeue_person; and person per_son; are two different objects. You are putting the name in one but printing the other so it's still garbage .

When you create object of person all the members are uninitialized so it's garbage value . and when you try to print it , it will print the garbage value on the stack .Hence you are getting this.

EDIT : As question is edited

get_person(point_person, 9);

After calling get_person() It will execute get_person() function's code. So in that there is local per_son object so whatever name you are putting is actually the local one and it will be automatically destroyed after exiting from get_person() printing the first_name there itself is good idea but one mistake is still there that you are doing printf() in the calling environment also which will give you the local object's first_name (i.e. garbage).

If you want to pass the person in the get_person() and want to print the same name at both places try this :

    person dequeue_person;
    person *point_person = &dequeue_person;
    get_person(point_person, 9);
    printf("%s", point_person->first_name);

void get_person(person *pers, int index)
{
    strcpy(pers->first_name, queue[(index+head)%QUEUE_MAX_SIZE].first_name);
    strcpy(pers->.last_name, queue[(index+head)%QUEUE_MAX_SIZE].last_name);
    strcpy(pers->pers_nbr, queue[(index+head)%QUEUE_MAX_SIZE].pers_nbr);

    printf("In get person First name : %s\n", pers->first_name);
}

In this case the pointer passed to the get_person() is pointing to the same object created in calling enviroment.see the implementation of get_person()

I hope you got it now.

Omkant
  • 9,018
  • 8
  • 39
  • 59
0

The contents of the structure are uninitialised. You need to set them to something.

You can initialise your struct like this:

struct person dequeue_person = { "joe", "blogs", "42" };

Or you can create an empty structure

struct person dequeue_person = { "", "", "" };

This is not uncommon to clear the entire struct:

struct person dequeue_person;
memset( &person, 0, sizeof(struct person) );

Edit.... I notice at the very end of your garbage output, the word "John" appears. Could it be that this is the end of your queue? ie element QUEUE_MAX_SIZE-1. Perhaps you have not initialised index and head correctly, or you are changing their values at the wrong time.

Or it could be that index+head is not the correct way to address your queue. Normally you would have a head and a tail index and you would not add them in this way. What you are doing implies that index is actually the number of elements in the queue.

paddy
  • 60,864
  • 6
  • 61
  • 103
  • Putting struct before creates a lot of errors like "incomplete type is not allowed". I tried it without using struct and it gave no errors, but returned no output. – Kraffs Nov 11 '12 at 22:28
  • Well the lack of output is because I'm clearing the struct to contain empty strings... When you create an empty variable and don't assign anything to it, what exactly do you expect it to contain? There must be something about your code that you are not showing us. – paddy Nov 11 '12 at 22:33
  • You need to show the code that populates `queue`, and state exactly what the values of `head` and `index` are. I don't think the string is being terminated correctly. – paddy Nov 11 '12 at 22:44
  • index is 9 and head is 0, queue[9].first_name contains "John" and printing per_son.first_name from within the function works just fine, it's when I try to use it outside of the function as the text gets garbled. – Kraffs Nov 11 '12 at 22:45
  • I figured it out! I had to get rid of per_son in the function aswell as change per_son in strcpy to pers. Now it returns the correct value without garbage. – Kraffs Nov 11 '12 at 22:50