954,492 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

string size, and concatenation

Obviously I have some wrong assumptions, because this prints "strsize = 8" no matter what.

I realize my use of system() might be misguided, so if you have comments on that don't hold back, just please help out with the string-thing aswell : )

BTW it's a 'wrapper' for shell one-liners, so it is actually supposed to run whatever input it gets in the shell it was called from.

if( system(command) == 0) {
		char* buff = malloc(sizeof(command)+42);
		strcat(buff, "notify-send \"notif finished\" \"Command: '");
		strcat(buff, command);
		strcat(buff, "'\"");
		system(buff);
		printf("strsize = %li\n", sizeof(buff));
	}
Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 
Obviously I have some wrong assumptions, because this prints "strsize = 8" no matter what.


Good call. buff is a pointer to char, so sizeof(buff) will always tell you what the size of a pointer to char is, not the length of the string it points to (if it points to a string at all, which isn't a safe assumption). What you want is the strlen() function, not sizeof.

Also note that strcat() expects the destination to be a valid string, which means you code is broken. This will fix it:

char* buff = malloc(sizeof(command)+42);

buff[0] = '\0'; /* Make buff a valid string */

strcat(buff, "notify-send \"notif finished\" \"Command: '");

Finally, it's good practice to check malloc() for failure. Otherwise you'll attempt to dereference a null pointer.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Thanks, that makes sense.
(can't believe the size '8' didn't ring a bell)
There is another thing though,
as far as I can tell, strcat depends on the string pointed to by its first parameter to be large enough to hold the two strings. but if I change the code to buff = malloc(sizeof(command)+2); (or pretty much any size at all, smaller than 42) the 'string' is expanded to be 42 characters long?

Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 
as far as I can tell, strcat depends on the string pointed to by its first parameter to be large enough to hold the two strings.


Correct, it's your job to ensure that the destination has enough room.but if I change the code to buff = malloc(sizeof(command)+2); (or pretty much any size at all, smaller than 42) the 'string' is expanded to be 42 characters long?
Expanded? No. C doesn't stop you from writing beyond the boundaries of an array. In Java, for example, you'll get an exception immediately, but C will happily write to memory you don't own and silently corrupt things. If you're lucky, you'll corrupt something that causes a fatal error, but in this case it seems as if you weren't lucky.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

But the printf() function still says the string length is 42? (44 when run with 'ls' as a parameter)
(heh - 42)
The call it later makes to system() also seems perfectly fine?

Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 

I understand your confusion, but please don't be tricked into thinking that the code isn't broken when you provide insufficient space for strcat().

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

OK. I just don't understand why it is actually working? Shouldn't the strlen only return 2 (or 4 with 'ls'), shouln't the string in the system(); call be cut of, and shouln't I get a segmentation fault?
You're right, Im pretty confused by this : )

Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 
Shouldn't the strlen only return 2 (or 4 with 'ls'), shouln't the string in the system(); call be cut of, and shouln't I get a segmentation fault?


Yes, yes, and yes. Or no, no, and no. Or any combination thereof. Undefined behavior meansany damn thing can happen, which includes working perfectly.

Narue
Bad Cop
Administrator
15,460 posts since Sep 2004
Reputation Points: 6,464
Solved Threads: 1,401
 

Ahh, well. at least that makes debugging easy..
How the hell do you find errors then? Only thanks to you I just realized the +42 should be + 43 (to include the string terminator).

BTW, if I do a if(buff) {*print errormessage and exit(1)*} to check if malloc returned NULL, do I still need to do a buff[0] = '\0' because malloc() doesn't guarantee anything about the data it returns a pointer to, or are we all good on the string when malloc succeeds?

Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 

If "malloc() doesn't guarantee anything about the data it returns a pointer to" what do you think that means about your buffer?

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

That it could contain anything?
The reference I'm using says strcat will append string2 to the end of string1, so we add a string terminator to the beginning of buff, to make sure strcat will write from buff[0], even if other elements contain a terminator. So yes, buff[0] = '\0' is necessary.
Guess I could figured that out : )

Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 
That it could contain anything? The reference I'm using says strcat will append string2 to the end of string1, so we add a string terminator to the beginning of buff, to make sure strcat will write from buff[0], even if other elements contain a terminator. So yes, buff[0] = '\0' is necessary. Guess I could figured that out : )


And you did, too! :)

WaltP
Posting Sage w/ dash of thyme
Moderator
10,505 posts since May 2006
Reputation Points: 3,348
Solved Threads: 944
 

Well thanks, both of you : )

Bladtman242
Junior Poster
176 posts since Dec 2008
Reputation Points: 18
Solved Threads: 4
 

This question has already been solved

Post: Markdown Syntax: Formatting Help
You