Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C sprintf array char pointers

Tags:

arrays

c

pointers

Could anyone tell me what am i doing wrong over here? Why does my program segfault ? I am trying to insert a third string between string1 and string2.

#include <stdio.h>

int main (void) 
{
char *string1 = "HELLO";
char *string2 = "WORLD";
char *stringX  = "++++";
char *string3;
printf ("%s,%s\n",string1,string2);
sprintf(string3,"%s%s%s",string1,stringX,string2);
printf ("NewVar: %s",string3);
}

Why doesn't sprintf store the resultant value at the memory address pointed by string3? It works when i declare string3 as an ordinary array but not when its a pointer to char array.

I thought string3 wasnt pointing to any memory location, but it does seem to when i do printf("%p",string3);

Output:

# ./concat
HELLO,WORLD,0x40042
like image 273
user2953313 Avatar asked Nov 04 '13 16:11

user2953313


People also ask

How to define pointer to char in C?

ptr[1] is *(ptr + 1) which is a character at the 1st location of string str . When we increment a pointer, it gets incremented in steps of the object size that the pointer points to. Here, ptr is pointer to char so, ptr+1 will give address of next character and *(ptr + 1) give the character at that location.


2 Answers

Imagine you have a pile of cash that you want to put in a briefcase. What do you need? You have to measure the size of the cash to know how big a briefcase to use, and you need a handle to conveniently carry the cash around.

The cash is your strings. The briefcase is memory space. The briefcase handle is the pointer.

  1. Measure your cash: strlen(string1) + strlen(string2) + strlen(stringX). Call this "total".
  2. Now get a big enough briefcase: malloc(total+1)
  3. And put a handle on it: string3

Cobbling all that together...

char *string3 = malloc(strlen(string1)+strlen(stringX)+strlen(string2)+1);
sprintf(string3, "%s%s%s", string1, stringX, string2);

So what was wrong with the first attempt? You had no briefcase. You have cash, and you have a handle, but no briefcase in the middle. It appeared to work, in a random kind of way, because the compiler gave you a dirty dumpster to hold the cash. Sometimes the dumpster has room, sometimes it doesn't. When it doesn't, we call that "segmentation fault".

Whenever you have data, you have to allocate space for that data. The compiler allocates space for your constant strings, like "HELLO". But you have to allocate space for strings built at run-time.

like image 101
bishop Avatar answered Oct 13 '22 19:10

bishop


sprintf does store the value there. The problem is that the pointer string3 has uninitialized value, so you're just overwriting random memory.

One option you have is to use static string buffer:

char string3[20];
snprintf(string3, sizeof(string3), "Hello!");

Or, you can use asprintf on GNU libc-based systems to allocate proper space automatically:

char * string3;
asprintf(&string3, "Hello!");
// ... after use
free(string3); // free the allocated memory
like image 10
che Avatar answered Oct 13 '22 18:10

che