what is wrong with printf

what am i doing wrong?
i am just changing the position of printf arguments and %s is not reading the string it the first code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    unsigned long long id;
    char *name;
}student;

int main()
{
    student msteel;
    msteel.id = 34443215;
    msteel.name = (char*)malloc(8*sizeof(char));
    msteel.name = "kiel";
    printf("%d\n%s",msteel.id,msteel.name);  //problem is here
    free(msteel.name);
    return 0;
}


34443215
(null)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    unsigned long long id;
    char *name;
}student;

int main()
{
    student msteel;
    msteel.id = 34443215;
    msteel.name = (char*)malloc(8*sizeof(char));
    msteel.name = "kiel";
    printf("%s\n%d",msteel.name,msteel.id); // working perfectly
    free(msteel.name);
    return 0;
}


kiel
34443215


am i doing some stupid mistake?
Last edited on
I think so. I think printf have an "optimization" that uses multithreading or somthing, so in the first example, outputting msteel.name is done AFTER the call to free(). Try adding \n to the end of the format string, MAYBE it could help, I don't know.
sigh
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long long unsigned int’ [-Wformat]

Also msteel.name = "kiel"; change the pointer, so memory leak and bad free.
Last edited on
The printf code used to indicate an unsigned long long is commonly %llu, not %d. Use the right code, and it'll work. Your implementation may use something other than %llu. My example code below uses %llu, since that's what my implementation uses.

Note also that you don't need to allocate or free memory, since you're not actually writing the letters into anything; you're making the char* msteel.name point at the string literal written into the binary executable. Trying to use free on a pointer that points at that string literal is a very bad idea.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>

typedef struct
{
    unsigned long long id;
    char *name;
}student;

int main()
{
    student msteel;
    msteel.id = 34443215;
    msteel.name = "kiel";
    printf("%llu \n%s",msteel.id,msteel.name);  //problem is here
	return 0;
}


Edit: I've been... NNNIINNNN..JARED!
Last edited on
Thanks.
The problem here is that you tell the printf function that you pass it a signed integer, but what you actually pass is a unsigned 8-byte integer, so when it advances to the next argument, it interprets the next four bytes as a pointer to a string, which is zero and it prints exactly that: (null).

So there's a couple of ways you can approach this:
1) use simple unsigned long and use %u modifier to print it (why do you need long long anyway?)
2) change to type-safe c++ style handling of streams (better option):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <string>

struct student
{
    unsigned long long id;
    std::string name;
};

int main()
{
    student msteel;
    msteel.id = 34443215;
    msteel.name = "kiel";
    std::cout << msteel.id << "\n" << msteel.name << std::endl;
     return 0;
}


If you wish to stick to C-style, there's one more thing for you to note.
When you use a literal string (such as "kiel") in code, the memory for it is allocated inside the executable and is loaded to memory with it. So when you allocate a pointer msteel.name and then assign "kiel" to it, you effectively lose the original allocated address (and a free call will fail).
So, again, you have two options:
1) use the address of the literal string "kiel" and avoid any allocations by simply removing lines 14 and 17
2) copy the string from the executable-preallocated memory to the address you allocated. Then instead of line 15 you should write (don't forget to include string.h):
strcpy(msteel.name, "kiel");

However, I really recommend to use type-safe C++ style.
Last edited on
Thanks again everyone for great explanation.
that really helped me a lot.
Topic archived. No new replies allowed.