-1

First version: (Works)

//Using sprintf
int index = 56;
char filename[64], * suffix = "txt";
sprintf(filename, "log_%d.%s", index, suffix);
lr_output_message ("The new file name is %s", filename);
//This works

Second version: (Does not work)

 //Using sprintf 
int index = 56;
char *filename, * suffix = "txt";
sprintf(filename, "log_%d.%s", index, suffix);
lr_output_message ("The new file name is %s", filename);
//Fails with invalid parameter passed to function
Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
Raghu Dev
  • 109
  • 4
  • 13

2 Answers2

2
  • Your first version (is correct and) works, because there is (enough) memory allocated for filename, which is a char array.

    char filename[64]. //....
    
  • Your second version (is incorrect and) does not work, because there is no memory allocation for filename, which you define as a pointer.

    char *filename,//...
    

This does not allocate memory to the pointer automatically.

In other words, the pointer is not pointing to any valid memory address. So, trying to access the memory pointed by the pointer is invalid and invokes undefined behaviour.

Solution: You need to allocate memory to the pointer before you use it. You can use malloc() and family functions to allocate memory to the pointer.

Also, one you allocate memory and the usage is done. you've to release the allocated memory using free()

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
  • But I can define strings like char name[5]="raghu" and char *name="raghu", both works. – Raghu Dev Jun 15 '15 at 07:20
  • 1
    @RaghuDev `char name[5]` is an array, initialized with `"raghu"` (**which is not null-terminated, BTW**), `char *name` is a pointer pointing to the base address of a string literal `"raghu",`. These two _are_ quite different actually. :-) – Sourav Ghosh Jun 15 '15 at 07:23
1

In the second case you have to allocate space in memory for filename, using malloc()

char *filename = malloc(64);

If you do not allocate space you will have undefined behaviour because of you are writing to a not initialized pointer.

Remember to always check the return of malloc:

if (filename != NULL)
{
   // your code ...
}
else
{
   printf("No space available for filename");
}

Once you allocate memory and the usage is done. you've to release the allocated memory using free()

LPs
  • 16,045
  • 8
  • 30
  • 61
  • But I can define strings like char name[5]="raghu" and char *name="raghu", both works. – Raghu Dev Jun 15 '15 at 07:20
  • 1
    Yes, because if you initialize your char* the compiler allocate statically a string and initialize the pointer to that string. – LPs Jun 15 '15 at 07:23
  • So if I use sprintf does it not mean initializing like char *name="raghu". – Raghu Dev Jun 15 '15 at 07:25
  • 1
    @RaghuDev: `sprintf()` does not allocate the space for the string — you have to do the allocation before calling it. It's better to use `snprintf()` as then you can tell it how much space it can use, and it won't overwrite beyond the end of the space. You can find out how much space is needed by sending a null pointer in place of a buffer (the return value is the number of bytes needed). – Jonathan Leffler Jun 15 '15 at 07:28
  • Thank you Jonathan, understood now. – Raghu Dev Jun 15 '15 at 07:29
  • @RaghuDev The point is to init your pointer. In your second case you are defining a pointer that point to what? Nothing because of is not init. If you use char *name="raghu", your pointer is initializaed, but to a memory that cannot be changed: it is read only. As I wrote, to use sprintf, you have to init a pointer by malloc to have a "space" in memory where to write your strings. – LPs Jun 15 '15 at 07:30