1

I've been looking for an answer to my question but I couldn't find any.

I've read several times the difference of malloc and calloc. If you have an issue with speed, you should use malloc since calloc allocates + initializes the buffer to 0.

Now, in my case, I should stick to malloc because its faster, but I still want to make sure that Id still get the correct data.

Does a call to strcpy after malloc is as good as calling calloc? I know that calloc isnt capable of copying a value of string one to the other. But I want to know if it is as safe as calloc since you used strcpy?


[update from comment:]

I declare and allocate the requersted memory..

char * commands = malloc(1000); 

Then compose the awk commands that I need and save it in commands.

strcpy(commands,"awk '{ print $0}' running-config.txt" ); 

That's how I used it.

alk
  • 69,737
  • 10
  • 105
  • 255
user3714598
  • 1,733
  • 5
  • 28
  • 45
  • "If you have an issue with speed, you should use malloc since calloc allocates + initializes the buffer to 0." - no, this depends on the operating system's virtual memory strategy. Some are faster to `calloc` than `malloc` – M.M Aug 11 '14 at 11:23
  • I added the information from your comment below to your question. As it should have been there in the first place. – alk Aug 11 '14 at 11:38
  • Related: [Why malloc+memset is slower than calloc?](http://stackoverflow.com/q/2688466/12892) – Cristian Ciupitu Aug 08 '15 at 03:23

4 Answers4

3

Does a call to strcpy after malloc is as good as calling calloc?

No, as strcpy(buffer, "") only sets the memory's 1st byte to 0, whereas calloc() zeros out the entire memory allocated.

strcpy(buffer, ""); is equivalent to buffer[0] = '\0';. I tend to say the latter is faster.

Whether strcpy()'s behaviour is enough of initialisation depends on the context/use-case.


Update:

As per your updated question, there does not seem to be any need to initialise the memory on allocation. (e.g. by using calloc(), as the call to strcpy() does it. But be aware that strcpy() leaves uninitialsed all unused memory (out of the allcoated memory). That is only strlen("awk '{ print $0}' running-config.txt") + 1 bytes out of the 1000 bytes allocated get initialised.

alk
  • 69,737
  • 10
  • 105
  • 255
  • so here's the summary of my code char * commands = malloc(10); strcpy(commands, "awkCommand"); strcat(commands, "other commands"); So in my case, I'm doing it right, right? since strcat will look for the 0 then concatenate the string from there. The only problem is, what if the allocated memory is occupied with garbage and the length of the string that I need to put in the command is 7, my string has a garbage at the end of it. If I memcpy'ed that same memory, garbage is included in the copy unless I use strcpy. Am I right? – user3714598 Aug 11 '14 at 11:47
  • You shall never copy/concatenate more characters to the `char` buffer then you allocate minus 1 (one is needed for the trailing `0`-terminator). @user3714598 – alk Aug 11 '14 at 11:52
  • As much as I want to, I can't give your answer another vote up though. My reputation's 7 only. Many thanks!! :D – user3714598 Aug 11 '14 at 11:56
1

Actually calling memset after malloc is closer to calling calloc, than the option you suggest. Still using memset after malloc will be in the best case as fast as calloc. If you need to be sure that the memory is initialized to 0 there is no better option than using calloc.

Ivaylo Strandjev
  • 69,226
  • 18
  • 123
  • 176
0

since commands variable is of char *, you probably interpret as null-terminated character array (buffer), so to initialize,

commands[0] = 0; 

is good enough to have null terminated empty string, and whenever you have a real string to copy you may use strcpy that copies all characters from source to destination including the null terminating character. You have to be careful about buffer overflow. If you are not sure about buffer overflow, safe would be to use strncpy instead, e.g.

const int SIZE = 1000; // or #define SIZE 1000
char * commands = malloc(SIZE);
strncpy(commands, src, SIZE-1 );
command[SIZE-1] = 0;
Dr. Debasish Jana
  • 6,980
  • 4
  • 30
  • 69
0

malloc allocates a chunk of data which contains garbage values. Simplified example:

char* str = malloc(10);

str now points at memory which could contain anything, lets assume these contents:

G A R B A G E 1 2 3

And then if you do a strcpy(str, "hello"), the memory will look like:

h e l l o 0 E 1 2 3

If you had instead used calloc(1, sizeof(char)), the memory would have been:

0 0 0 0 0 0 0 0 0 0

And after strcpy(str, "hello"):

h e l l o 0 0 0 0 0

These two are completely equivalent in terms of functionality and both will work just fine. The only difference is that calloc is ever so slightly slower, since it writes zeroes to the last bytes of memory, that aren't used by the program.

The practice I would recommend:

size_t n = sizeof("hello");

char* str = malloc(n);
if(str == NULL) 
  handle_error();
memcpy(str, "hello", n);

memcpy is faster than strcpy and also enforces you to specify a buffer size. Also note that in the above case, n will actually be 6, because the string literal "hello" consists of 5 characters + 1 null termination. Programmers have a tendency to forget the null termination, like for example only mallocing strlen() bytes of space, while they actually need strlen() + 1.

Lundin
  • 195,001
  • 40
  • 254
  • 396