3

I am a newbie to C still, and I am having a problem with the memset function.

I pass a char * to a function, and inside this function I create an array, and then use memset to set each value. I have been using dbx to watch this variable as it enters the function, and for some reason it gets set to "" after we pass memset.

Firstly, why does this happen? I'm assuming that memset must be resetting the memory where the char * is located?

Secondly, is there a better way to set each element as "0"?

Here is my code:

static char *writeMyStr(char *myStr, int wCount) {

   // here myStr is set to "My String is populated"  

   char **myArr;
   myArr = (char **) malloc(sizeof(char *) * wCount);
   memset(myArr, 0, sizeof(char *) * wCount);   // myStr is set to ""

   ... populate array ... 

}
Doug Molineux
  • 12,283
  • 25
  • 92
  • 144
  • Some people say you should not cast the return value of malloc. – Wug Jul 17 '12 at 18:52
  • 1
    Those people are idiots. The return value of malloc is a void *. You can't do anything with it without casting it, either implicitly or explicitly. – Charlie Martin Jul 17 '12 at 18:53
  • 3
    @CharlieMartin This is C, not C++. In C++ you need to cast. – Mysticial Jul 17 '12 at 18:54
  • First of all in C++ you should use new instead of malloc :) – Blood Jul 17 '12 at 18:54
  • 2
    @CharlieMartin: Or perhaps those people just know C. – Kerrek SB Jul 17 '12 at 18:55
  • 1
    @Blood: Unless you need to call `malloc`, because you have to interact with C code, for example. – rodrigo Jul 17 '12 at 18:55
  • @rodrigo Okay, fair enough :) – Blood Jul 17 '12 at 18:55
  • 1
    @Mystical in C, if you don't cast it lint will (properly) complain. It's actually possible in C for pointers to have different sizes and for an uncast assignment to lose things. – Charlie Martin Jul 17 '12 at 18:56
  • @KerrekSB, if they did they'd know why it's useful to cast. – Charlie Martin Jul 17 '12 at 18:56
  • 1
    @CharlieMartin, in C, an object pointer can be converted to `void *` and vice versa without a cast. Casting the return value of `malloc` in C is a bad idea. http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – Alok Singhal Jul 17 '12 at 18:58
  • 1
    Your code looks fine. Use valgrind to find the *real* problem. – bmargulies Jul 17 '12 at 18:58
  • @CharlieMartin, also there is no such thing as "implicit cast". A cast is by definition, explicit. You can say "implicit conversion", but that is the same as not casting. – Alok Singhal Jul 17 '12 at 18:59
  • @CharlieMartin: Pointers may have different sizes, but an explicit cast won't change anything. – Oliver Charlesworth Jul 17 '12 at 19:05
  • At least in the code you display, `myStr` is never set to anything, and never used. Might it be that myStr is `""` because that's how it was set by the caller? **Update** You do realize that `""` is simply a byte of `\0`, right? is it possible you're calling this with the pointer pointing to the END of a string? – Charlie Martin Jul 17 '12 at 18:54
  • Sorry, I added some text to my answer, dbx indicates that `myStr` does have text in it, before we reach the memset line. – Doug Molineux Jul 17 '12 at 18:56
  • We still need to see the caller. – Charlie Martin Jul 17 '12 at 18:57
  • Sorry, what's the "caller"? Is this how myStr is originally set? – Doug Molineux Jul 17 '12 at 18:58
  • What does it say the value of myArr is? – Wug Jul 17 '12 at 18:59
  • The caller is the code that calls the callee, that is the code you're showing us. We can't see what you're doing; we can't tell you what's wrong. – Charlie Martin Jul 17 '12 at 19:01
  • Interestingly, the memory address of myStr and myArr are the same – Doug Molineux Jul 17 '12 at 19:03
  • @PeteHerbertPenito, can you post real (full) code that exhibits this behavior? – Alok Singhal Jul 17 '12 at 19:03
  • "is it possible you're calling this with the pointer pointing to the END of a string?" NO, as I have pointed out, myStr is populated at the beginning of the function. I don't understand what you're trying to say here, what does it matter about the "callee" or "caller" the string exists within the function, so obviously it was passed properly – Doug Molineux Jul 17 '12 at 19:13

2 Answers2

11

Are you looking for zero the character, or zero the number? When initializing an array as so:

memset(arr, 0, count);

It is equivalent to

memset(arr, '\0', count);

Because 0=='\0'. The length of a string is the position of the first null terminator, so your string is zero-length, because the array backing it is filled with zeros. The reason people do this is so that as they add things to the string, they don't need to re-null-terminate it.

If you want your string to be "0000"... use the character zero:

memset(arr, '0', count);

But remember to null-terminate it:

arr[count-1] = '\0';
Dave
  • 10,964
  • 3
  • 32
  • 54
2

If you're trying to zero-fill the array initially, it is better use calloc rather than malloc.

All malloc does it give you a block of memory with random, indeterminate values. Whereas calloc gives you a block of memory and zero-fills it, guaranteeing that you won't have junk in there.

ardent
  • 2,453
  • 1
  • 16
  • 15
  • 1
    @CharlieMartin, and this is an attempt to answer the second part of his question, if there is a better way of setting each element to zero. Eliminating the need for a memset and giving more leeway in determining what exactly is clearing myStr. – ardent Jul 17 '12 at 19:05